diff --git a/MediaBrowser.Api/EnvironmentService.cs b/MediaBrowser.Api/EnvironmentService.cs index 618eeae5df..d96b69cc4d 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 d3d76f4f27..1513d0d05d 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 8c7499a7cc..3081d6cd05 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 0729987d9e..2abb4e9148 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 35c658f912..47ea2aa2ab 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 098c9f72a9..8c4005d479 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 896e1d438e..1ebfb357e1 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -123,6 +123,10 @@ {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} MediaBrowser.Model + + {7c11010e-179a-49b7-bfb2-f1656f5e71ad} + MediaBrowser.Networking + diff --git a/MediaBrowser.Api/PackageService.cs b/MediaBrowser.Api/PackageService.cs index 028242e725..64338e5f09 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 1f906f814c..b2e82d4d6e 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 e79ab90dae..d1c7f451f2 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 7921d024a5..cf0be35a2b 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 0c99b921a6..991c87b5fd 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 0586b2b5ea..2c4fef3522 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 51197affb8..bad55d51c4 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 d4490d856a..47dcbbf4db 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 c79c2da284..9c66f2bcf8 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 ad8c38dad5..0000000000 --- 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 -{ - /// - /// Class DataSerializer - /// - public static class DataSerializer - { - /// - /// Gets or sets the dynamically created serializer. - /// - /// The dynamic serializer. - public static TypeModel DynamicSerializer { get; set; } - - /// - /// Deserializes an object - /// - /// The stream. - /// The format. - /// The type. - /// System.Object. - /// - 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(); - } - - /// - /// Serializes to json. - /// - /// The obj. - /// System.String. - 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(); - } - } - - /// - /// Configures this instance. - /// - public static void Configure() - { - } - } -} diff --git a/MediaBrowser.ApiInteraction.Portable/MediaBrowser.ApiInteraction.Portable.csproj b/MediaBrowser.ApiInteraction.Portable/MediaBrowser.ApiInteraction.Portable.csproj index 9730663079..aaf5a3bd8e 100644 --- a/MediaBrowser.ApiInteraction.Portable/MediaBrowser.ApiInteraction.Portable.csproj +++ b/MediaBrowser.ApiInteraction.Portable/MediaBrowser.ApiInteraction.Portable.csproj @@ -38,10 +38,15 @@ AsyncHttpClient.cs + + NewtonsoftJsonSerializer.cs + + + SerializationFormats.cs + Properties\SharedVersion.cs - BaseApiClient.cs @@ -52,9 +57,6 @@ IAsyncHttpClient.cs - - SerializationFormats.cs - @@ -66,9 +68,6 @@ ..\packages\Newtonsoft.Json.4.5.11\lib\portable-net40+sl4+wp7+win8\Newtonsoft.Json.dll - - ..\packages\protobuf-net.2.0.0.621\lib\portable-sl4+net40+wp7+windows8\protobuf-net.dll - ..\packages\Microsoft.Net.Http.2.1.3-beta\lib\portable-net40+sl4+win8+wp71\System.Net.Http.dll diff --git a/MediaBrowser.ApiInteraction.Portable/packages.config b/MediaBrowser.ApiInteraction.Portable/packages.config index c3efe6da4e..795bf139cd 100644 --- a/MediaBrowser.ApiInteraction.Portable/packages.config +++ b/MediaBrowser.ApiInteraction.Portable/packages.config @@ -5,5 +5,4 @@ - \ No newline at end of file diff --git a/MediaBrowser.ApiInteraction/ApiClient.cs b/MediaBrowser.ApiInteraction/ApiClient.cs index e7d4e6eff1..5268c7e1f7 100644 --- a/MediaBrowser.ApiInteraction/ApiClient.cs +++ b/MediaBrowser.ApiInteraction/ApiClient.cs @@ -45,6 +45,15 @@ namespace MediaBrowser.ApiInteraction HttpClient = httpClient; } + /// + /// Initializes a new instance of the class. + /// + /// The logger. + public ApiClient(ILogger logger) + : this(logger, new AsyncHttpClient()) + { + } + /// /// Sets the authorization header. /// @@ -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); } /// @@ -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); } /// @@ -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); } /// @@ -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 ec8176d8a1..c6701cac08 100644 --- a/MediaBrowser.ApiInteraction/AsyncHttpClient.cs +++ b/MediaBrowser.ApiInteraction/AsyncHttpClient.cs @@ -45,7 +45,7 @@ namespace MediaBrowser.ApiInteraction /// The cancellation token. /// Task{Stream}. /// - public async Task GetStreamAsync(string url, ILogger logger, CancellationToken cancellationToken) + public async Task GetAsync(string url, ILogger logger, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); diff --git a/MediaBrowser.ApiInteraction/BaseApiClient.cs b/MediaBrowser.ApiInteraction/BaseApiClient.cs index 242fc23591..4bd4ace508 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; @@ -21,10 +22,23 @@ namespace MediaBrowser.ApiInteraction /// The logger. protected ILogger Logger { get; private set; } + /// + /// Gets the protobuf serializer. + /// + /// The protobuf serializer. + public IProtobufSerializer ProtobufSerializer { get; private set; } + + /// + /// Gets the json serializer. + /// + /// The json serializer. + public IJsonSerializer JsonSerializer { get; private set; } + /// /// Initializes a new instance of the class. /// /// The logger. + /// The json serializer. /// logger 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; } /// @@ -90,22 +104,11 @@ namespace MediaBrowser.ApiInteraction } } - private SerializationFormats _serializationFormat = SerializationFormats.Protobuf; /// /// Gets the default data format to request from the server /// /// The serialization format. - public SerializationFormats SerializationFormat - { - get - { - return _serializationFormat; - } - set - { - _serializationFormat = value; - } - } + public SerializationFormats SerializationFormat { get; set; } /// /// Resets the authorization header. @@ -790,7 +793,39 @@ namespace MediaBrowser.ApiInteraction protected T DeserializeFromStream(Stream stream) where T : class { - return (T)DataSerializer.DeserializeFromStream(stream, SerializationFormat, typeof(T)); + return (T)DeserializeFromStream(stream, typeof(T), SerializationFormat); + } + + /// + /// Deserializes from stream. + /// + /// The stream. + /// The type. + /// The format. + /// System.Object. + /// + 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(); + } + + /// + /// Serializers to json. + /// + /// The obj. + /// System.String. + protected string SerializeToJson(object obj) + { + return JsonSerializer.SerializeToString(obj); } /// diff --git a/MediaBrowser.ApiInteraction/DataSerializer.cs b/MediaBrowser.ApiInteraction/DataSerializer.cs deleted file mode 100644 index cc13d55c88..0000000000 --- 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 -{ - /// - /// Class DataSerializer - /// - public static class DataSerializer - { - /// - /// Gets or sets the dynamically created serializer. - /// - /// The dynamic serializer. - public static TypeModel DynamicSerializer { get; set; } - - /// - /// Deserializes an object - /// - /// The stream. - /// The format. - /// The type. - /// System.Object. - /// - 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(); - } - - /// - /// Serializes to json. - /// - /// The obj. - /// System.String. - public static string SerializeToJsonString(object obj) - { - return JsonSerializer.SerializeToString(obj, obj.GetType()); - } - - /// - /// Configures this instance. - /// - 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 edd11829a6..0837f150fa 100644 --- a/MediaBrowser.ApiInteraction/IAsyncHttpClient.cs +++ b/MediaBrowser.ApiInteraction/IAsyncHttpClient.cs @@ -24,7 +24,7 @@ namespace MediaBrowser.ApiInteraction /// The logger. /// The cancellation token. /// Task{Stream}. - Task GetStreamAsync(string url, ILogger logger, CancellationToken cancellationToken); + Task GetAsync(string url, ILogger logger, CancellationToken cancellationToken); /// /// Deletes the async. diff --git a/MediaBrowser.ApiInteraction/MediaBrowser.ApiInteraction.csproj b/MediaBrowser.ApiInteraction/MediaBrowser.ApiInteraction.csproj index 0d9938891f..a4a9091928 100644 --- a/MediaBrowser.ApiInteraction/MediaBrowser.ApiInteraction.csproj +++ b/MediaBrowser.ApiInteraction/MediaBrowser.ApiInteraction.csproj @@ -32,19 +32,13 @@ 4 - - False - ..\packages\protobuf-net.2.0.0.621\lib\net40\protobuf-net.dll - - - False - ..\packages\ServiceStack.Text.3.9.37\lib\net35\ServiceStack.Text.dll + + ..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll - @@ -58,11 +52,10 @@ - + - diff --git a/MediaBrowser.ApiInteraction/NewtonsoftJsonSerializer.cs b/MediaBrowser.ApiInteraction/NewtonsoftJsonSerializer.cs new file mode 100644 index 0000000000..f5b43669ea --- /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 +{ + /// + /// Class NewtonsoftJsonSerializer + /// + public class NewtonsoftJsonSerializer : IJsonSerializer + { + /// + /// Serializes to stream. + /// + /// The obj. + /// The stream. + /// + /// obj + public void SerializeToStream(object obj, Stream stream) + { + throw new NotImplementedException(); + } + + /// + /// Deserializes from stream. + /// + /// The stream. + /// The type. + /// System.Object. + 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); + } + } + } + + /// + /// Deserializes from stream. + /// + /// + /// The stream. + /// ``0. + public T DeserializeFromStream(Stream stream) + { + return (T)DeserializeFromStream(stream, typeof(T)); + } + + /// + /// Deserializes from string. + /// + /// + /// The text. + /// ``0. + /// + public T DeserializeFromString(string text) + { + throw new NotImplementedException(); + } + + /// + /// Deserializes from string. + /// + /// The json. + /// The type. + /// System.Object. + /// + public object DeserializeFromString(string json, Type type) + { + throw new NotImplementedException(); + } + + /// + /// Serializes to string. + /// + /// The obj. + /// System.String. + 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(); + } + } + + /// + /// Serializes to bytes. + /// + /// The obj. + /// System.Byte[][]. + /// + public byte[] SerializeToBytes(object obj) + { + throw new NotImplementedException(); + } + + /// + /// Serializes to file. + /// + /// The obj. + /// The file. + /// + /// obj + public void SerializeToFile(object obj, string file) + { + throw new NotImplementedException(); + } + + /// + /// Deserializes from file. + /// + /// The type. + /// The file. + /// System.Object. + /// + public object DeserializeFromFile(Type type, string file) + { + throw new NotImplementedException(); + } + + /// + /// Deserializes from file. + /// + /// + /// The file. + /// ``0. + /// + public T DeserializeFromFile(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 99a65db5d7..0000000000 --- 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 - { - /// - /// Attemps to discover the server within a local network - /// - public static async Task 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; - } - - /// - /// Gets a random port number that is currently available - /// - 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 14eb42cace..b82a8b0dde 100644 --- a/MediaBrowser.ApiInteraction/packages.config +++ b/MediaBrowser.ApiInteraction/packages.config @@ -1,5 +1,4 @@  - - + \ 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 0000000000..c5af5059f3 --- /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 + { + /// + /// Gets or sets the logger. + /// + /// The logger. + public ILogger Logger { get; protected set; } + + /// + /// The container + /// + protected readonly Container Container = new Container(); + + /// + /// Gets assemblies that failed to load + /// + public List FailedAssemblies { get; protected set; } + + /// + /// Gets all types within all running assemblies + /// + /// All types. + public Type[] AllTypes { get; protected set; } + + /// + /// Gets all concrete types. + /// + /// All concrete types. + public Type[] AllConcreteTypes { get; protected set; } + + /// + /// The disposable parts + /// + protected readonly List DisposableParts = new List(); + + /// + /// The _protobuf serializer initialized + /// + private bool _protobufSerializerInitialized; + /// + /// The _protobuf serializer sync lock + /// + private object _protobufSerializerSyncLock = new object(); + /// + /// Gets a dynamically compiled generated serializer that can serialize protocontracts without reflection + /// + private IProtobufSerializer _protobufSerializer; + /// + /// Gets the protobuf serializer. + /// + /// The protobuf serializer. + 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; + } + } + + /// + /// Initializes a new instance of the class. + /// + protected BaseApplicationHost() + { + FailedAssemblies = new List(); + } + + /// + /// Gets the composable part assemblies. + /// + /// IEnumerable{Assembly}. + protected abstract IEnumerable GetComposablePartAssemblies(); + + /// + /// Discovers the types. + /// + protected void DiscoverTypes() + { + FailedAssemblies.Clear(); + + AllTypes = GetComposablePartAssemblies().SelectMany(GetTypes).ToArray(); + + AllConcreteTypes = AllTypes.Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType).ToArray(); + } + + /// + /// 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 + /// + /// The assembly. + /// IEnumerable{Type}. + /// assembly + protected IEnumerable 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); + } + } + + /// + /// Creates an instance of type and resolves all constructor dependancies + /// + /// The type. + /// System.Object. + public object CreateInstance(Type type) + { + try + { + return Container.GetInstance(type); + } + catch + { + Logger.Error("Error creating {0}", type.Name); + + throw; + } + } + + /// + /// Registers the specified obj. + /// + /// + /// The obj. + protected void RegisterSingleInstance(T obj) + where T : class + { + Container.RegisterSingle(obj); + } + + /// + /// Registers the specified func. + /// + /// + /// The func. + protected void Register(Func func) + where T : class + { + Container.Register(func); + } + + /// + /// Registers the single instance. + /// + /// + /// The func. + protected void RegisterSingleInstance(Func func) + where T : class + { + Container.RegisterSingle(func); + } + + /// + /// Resolves this instance. + /// + /// + /// ``0. + public T Resolve() + { + return (T)Container.GetRegistration(typeof(T), true).GetInstance(); + } + + /// + /// Resolves this instance. + /// + /// + /// ``0. + public T TryResolve() + { + var result = Container.GetRegistration(typeof(T), false); + + if (result == null) + { + return default(T); + } + return (T)result.GetInstance(); + } + + /// + /// Registers the specified service type. + /// + /// Type of the service. + /// Type of the concrete. + protected void Register(Type serviceType, Type implementation) + { + Container.Register(serviceType, implementation); + } + + /// + /// Loads the assembly. + /// + /// The file. + /// Assembly. + 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; + } + } + + /// + /// Gets the exports. + /// + /// + /// if set to true [manage liftime]. + /// IEnumerable{``0}. + public IEnumerable GetExports(bool manageLiftime = true) + { + var currentType = typeof(T); + + Logger.Info("Composing instances of " + currentType.Name); + + var parts = AllConcreteTypes.Where(currentType.IsAssignableFrom).Select(CreateInstance).Cast().ToArray(); + + if (manageLiftime) + { + DisposableParts.AddRange(parts.OfType()); + } + + return parts; + } + + /// + /// Gets the current application version + /// + /// The application version. + public Version ApplicationVersion + { + get + { + return GetType().Assembly.GetName().Version; + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + 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 736a15d423..acd798d733 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -41,6 +41,9 @@ ..\packages\ServiceStack.Text.3.9.37\lib\net35\ServiceStack.Text.dll + + ..\packages\SimpleInjector.2.0.0-beta5\lib\net40-client\SimpleInjector.dll + @@ -54,8 +57,10 @@ Properties\SharedVersion.cs + + diff --git a/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs similarity index 61% rename from MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs rename to MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index 09ceaa9aee..7fa30f4ae0 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 { /// - /// Represents a task that can be executed at a scheduled time + /// Class ScheduledTaskWorker /// - /// The type of the T kernel type. - public abstract class BaseScheduledTask : IScheduledTask - where TKernelType : class, IKernel + public class ScheduledTaskWorker : IScheduledTaskWorker { /// - /// Gets the kernel. + /// Gets or sets the scheduled task. /// - /// The kernel. - protected TKernelType Kernel { get; private set; } + /// The scheduled task. + public IScheduledTask ScheduledTask { get; private set; } + + /// + /// Gets or sets the json serializer. + /// + /// The json serializer. + private IJsonSerializer JsonSerializer { get; set; } + + /// + /// Gets or sets the application paths. + /// + /// The application paths. + private IApplicationPaths ApplicationPaths { get; set; } /// /// Gets the logger. /// /// The logger. - protected ILogger Logger { get; private set; } + private ILogger Logger { get; set; } /// /// Gets the task manager. /// /// The task manager. - protected ITaskManager TaskManager { get; private set; } + private ITaskManager TaskManager { get; set; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The kernel. + /// The scheduled task. + /// The application paths. /// The task manager. + /// The json serializer. /// The logger. - /// kernel - 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); } /// @@ -89,7 +89,7 @@ namespace MediaBrowser.Common.ScheduledTasks { try { - return TaskManager.GetLastExecutionResult(this); + return JsonSerializer.DeserializeFromFile(GetHistoryFilePath()); } catch (IOException) { @@ -108,6 +108,33 @@ namespace MediaBrowser.Common.ScheduledTasks } } + /// + /// Gets the name. + /// + /// The name. + public string Name + { + get { return ScheduledTask.Name; } + } + + /// + /// Gets the description. + /// + /// The description. + public string Description + { + get { return ScheduledTask.Description; } + } + + /// + /// Gets the category. + /// + /// The category. + public string Category + { + get { return ScheduledTask.Category; } + } + /// /// Gets the current cancellation token /// @@ -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,45 +216,10 @@ namespace MediaBrowser.Common.ScheduledTasks ReloadTriggerEvents(false); - TaskManager.SaveTriggers(this, _triggers); + SaveTriggers(_triggers); } } - /// - /// Creates the triggers that define when the task will run - /// - /// IEnumerable{BaseTaskTrigger}. - public abstract IEnumerable GetDefaultTriggers(); - - /// - /// Returns the task to be executed - /// - /// The cancellation token. - /// The progress. - /// Task. - protected abstract Task ExecuteInternal(CancellationToken cancellationToken, IProgress progress); - - /// - /// Gets the name of the task - /// - /// The name. - public abstract string Name { get; } - - /// - /// Gets the description. - /// - /// The description. - public abstract string Description { get; } - - /// - /// Gets the category. - /// - /// The category. - public virtual string Category - { - get { return "Application"; } - } - /// /// The _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); } /// @@ -378,6 +370,128 @@ namespace MediaBrowser.Common.ScheduledTasks } } + /// + /// The _scheduled tasks configuration directory + /// + private string _scheduledTasksConfigurationDirectory; + /// + /// Gets the scheduled tasks configuration directory. + /// + /// The scheduled tasks configuration directory. + private string ScheduledTasksConfigurationDirectory + { + get + { + if (_scheduledTasksConfigurationDirectory == null) + { + _scheduledTasksConfigurationDirectory = Path.Combine(ApplicationPaths.ConfigurationDirectoryPath, "ScheduledTasks"); + + if (!Directory.Exists(_scheduledTasksConfigurationDirectory)) + { + Directory.CreateDirectory(_scheduledTasksConfigurationDirectory); + } + } + return _scheduledTasksConfigurationDirectory; + } + } + + /// + /// The _scheduled tasks data directory + /// + private string _scheduledTasksDataDirectory; + /// + /// Gets the scheduled tasks data directory. + /// + /// The scheduled tasks data directory. + private string ScheduledTasksDataDirectory + { + get + { + if (_scheduledTasksDataDirectory == null) + { + _scheduledTasksDataDirectory = Path.Combine(ApplicationPaths.DataPath, "ScheduledTasks"); + + if (!Directory.Exists(_scheduledTasksDataDirectory)) + { + Directory.CreateDirectory(_scheduledTasksDataDirectory); + } + } + return _scheduledTasksDataDirectory; + } + } + + /// + /// Gets the history file path. + /// + /// The history file path. + private string GetHistoryFilePath() + { + return Path.Combine(ScheduledTasksDataDirectory, Id + ".js"); + } + + /// + /// Gets the configuration file path. + /// + /// System.String. + private string GetConfigurationFilePath() + { + return Path.Combine(ScheduledTasksConfigurationDirectory, Id + ".js"); + } + + /// + /// Loads the triggers. + /// + /// IEnumerable{BaseTaskTrigger}. + private IEnumerable LoadTriggers() + { + try + { + return JsonSerializer.DeserializeFromFile>(GetConfigurationFilePath()) + .Select(ScheduledTaskHelpers.GetTrigger) + .ToList(); + } + catch (IOException) + { + // File doesn't exist. No biggie. Return defaults. + return ScheduledTask.GetDefaultTriggers(); + } + } + + /// + /// Saves the triggers. + /// + /// The triggers. + private void SaveTriggers(IEnumerable triggers) + { + JsonSerializer.SerializeToFile(triggers.Select(ScheduledTaskHelpers.GetTriggerInfo), GetConfigurationFilePath()); + } + + /// + /// Called when [task completed]. + /// + /// The start time. + /// The end time. + /// The status. + 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; + } + /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// @@ -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 c6eca29d1c..4b61492d66 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 /// /// The scheduled tasks. - public IScheduledTask[] ScheduledTasks { get; private set; } + public IScheduledTaskWorker[] ScheduledTasks { get; private set; } /// /// The _task queue @@ -27,19 +26,22 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks private readonly List _taskQueue = new List(); /// - /// The _logger + /// Gets or sets the json serializer. /// - private readonly ILogger _logger; + /// The json serializer. + private IJsonSerializer JsonSerializer { get; set; } /// - /// The _application paths + /// Gets or sets the application paths. /// - private readonly IApplicationPaths _applicationPaths; + /// The application paths. + private IApplicationPaths ApplicationPaths { get; set; } /// - /// The _json serializer + /// Gets the logger. /// - private readonly IJsonSerializer _jsonSerializer; + /// The logger. + private ILogger Logger { get; set; } /// /// Initializes a new instance of the class. @@ -50,24 +52,11 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// kernel 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[] { }; } /// @@ -77,7 +66,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks public void CancelIfRunningAndQueue() where T : IScheduledTask { - ScheduledTasks.OfType().First().CancelIfRunning(); + ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T)).CancelIfRunning(); QueueScheduledTask(); } @@ -88,7 +77,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks public void QueueScheduledTask() where T : IScheduledTask { - var scheduledTask = ScheduledTasks.OfType().First(); + var scheduledTask = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T)); QueueScheduledTask(scheduledTask); } @@ -99,27 +88,36 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// The task. 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); + } + + /// + /// Queues the scheduled task. + /// + /// The task. + 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,147 +155,11 @@ 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(); } - /// - /// The _scheduled tasks configuration directory - /// - private string _scheduledTasksConfigurationDirectory; - /// - /// Gets the scheduled tasks configuration directory. - /// - /// The scheduled tasks configuration directory. - private string ScheduledTasksConfigurationDirectory - { - get - { - if (_scheduledTasksConfigurationDirectory == null) - { - _scheduledTasksConfigurationDirectory = Path.Combine(_applicationPaths.ConfigurationDirectoryPath, "ScheduledTasks"); - - if (!Directory.Exists(_scheduledTasksConfigurationDirectory)) - { - Directory.CreateDirectory(_scheduledTasksConfigurationDirectory); - } - } - return _scheduledTasksConfigurationDirectory; - } - } - - /// - /// The _scheduled tasks data directory - /// - private string _scheduledTasksDataDirectory; - /// - /// Gets the scheduled tasks data directory. - /// - /// The scheduled tasks data directory. - private string ScheduledTasksDataDirectory - { - get - { - if (_scheduledTasksDataDirectory == null) - { - _scheduledTasksDataDirectory = Path.Combine(_applicationPaths.DataPath, "ScheduledTasks"); - - if (!Directory.Exists(_scheduledTasksDataDirectory)) - { - Directory.CreateDirectory(_scheduledTasksDataDirectory); - } - } - return _scheduledTasksDataDirectory; - } - } - - /// - /// Gets the history file path. - /// - /// The history file path. - private string GetHistoryFilePath(IScheduledTask task) - { - return Path.Combine(ScheduledTasksDataDirectory, task.Id + ".js"); - } - - /// - /// Gets the configuration file path. - /// - /// The task. - /// System.String. - private string GetConfigurationFilePath(IScheduledTask task) - { - return Path.Combine(ScheduledTasksConfigurationDirectory, task.Id + ".js"); - } - - /// - /// Called when [task completed]. - /// - /// The task. - /// The start time. - /// The end time. - /// The status. - 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; - } - - /// - /// Gets the last execution result. - /// - /// The task. - /// TaskResult. - public TaskResult GetLastExecutionResult(IScheduledTask task) - { - return _jsonSerializer.DeserializeFromFile(GetHistoryFilePath(task)); - } - - /// - /// Loads the triggers. - /// - /// The task. - /// IEnumerable{BaseTaskTrigger}. - public IEnumerable LoadTriggers(IScheduledTask task) - { - try - { - return _jsonSerializer.DeserializeFromFile>(GetConfigurationFilePath(task)) - .Select(ScheduledTaskHelpers.GetTrigger) - .ToList(); - } - catch (IOException) - { - // File doesn't exist. No biggie. Return defaults. - return task.GetDefaultTriggers(); - } - } - - /// - /// Saves the triggers. - /// - /// The task. - /// The triggers. - public void SaveTriggers(IScheduledTask task, IEnumerable triggers) - { - _jsonSerializer.SerializeToFile(triggers.Select(ScheduledTaskHelpers.GetTriggerInfo), GetConfigurationFilePath(task)); - } - /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs index 2ef0566587..a9c82c3578 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 /// /// Deletes old cache files /// - public class DeleteCacheFileTask : BaseScheduledTask + public class DeleteCacheFileTask : IScheduledTask { + /// + /// Gets or sets the kernel. + /// + /// The kernel. + private IKernel Kernel { get; set; } + /// + /// Gets or sets the logger. + /// + /// The logger. + private ILogger Logger { get; set; } + /// /// Initializes a new instance of the class. /// /// The kernel. - /// The task manager. /// The logger. - public DeleteCacheFileTask(IKernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + public DeleteCacheFileTask(IKernel kernel, ILogger logger) { + Kernel = kernel; + Logger = logger; } /// /// Creates the triggers that define when the task will run /// /// IEnumerable{BaseTaskTrigger}. - public override IEnumerable GetDefaultTriggers() + public IEnumerable GetDefaultTriggers() { var trigger = new DailyTrigger { TimeOfDay = TimeSpan.FromHours(2) }; //2am @@ -43,7 +54,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// The cancellation token. /// The progress. /// Task. - protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress progress) + public Task Execute(CancellationToken cancellationToken, IProgress progress) { return Task.Run(() => { @@ -90,7 +101,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// Gets the name of the task /// /// The name. - 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. /// /// The description. - 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. /// /// The category. - 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 dd00a71489..a7d8a68a04 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 /// /// Deletes old log files /// - public class DeleteLogFileTask : BaseScheduledTask + public class DeleteLogFileTask : IScheduledTask { + /// + /// Gets or sets the kernel. + /// + /// The kernel. + private IKernel Kernel { get; set; } + /// + /// Gets or sets the logger. + /// + /// The logger. + private ILogger Logger { get; set; } + /// /// Initializes a new instance of the class. /// /// The kernel. - /// The task manager. /// The logger. - public DeleteLogFileTask(IKernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + public DeleteLogFileTask(IKernel kernel, ILogger logger) { + Kernel = kernel; + Logger = logger; } /// /// Creates the triggers that define when the task will run /// /// IEnumerable{BaseTaskTrigger}. - public override IEnumerable GetDefaultTriggers() + public IEnumerable GetDefaultTriggers() { var trigger = new DailyTrigger { TimeOfDay = TimeSpan.FromHours(2) }; //2am @@ -43,7 +54,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// The cancellation token. /// The progress. /// Task. - protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress progress) + public Task Execute(CancellationToken cancellationToken, IProgress progress) { return Task.Run(() => { @@ -78,7 +89,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// Gets the name of the task /// /// The name. - 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. /// /// The description. - 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. /// /// The category. - 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 79c633c765..ac06f111a2 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 /// /// Class ReloadLoggerFileTask /// - public class ReloadLoggerFileTask : BaseScheduledTask + public class ReloadLoggerFileTask : IScheduledTask { + /// + /// Gets or sets the kernel. + /// + /// The kernel. + private IKernel Kernel { get; set; } + /// + /// Gets or sets the logger. + /// + /// The logger. + private ILogger Logger { get; set; } + /// /// Initializes a new instance of the class. /// /// The kernel. - /// The task manager. /// The logger. - public ReloadLoggerFileTask(IKernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + public ReloadLoggerFileTask(IKernel kernel, ILogger logger) { + Kernel = kernel; + Logger = logger; } /// /// Gets the default triggers. /// /// IEnumerable{BaseTaskTrigger}. - public override IEnumerable GetDefaultTriggers() + public IEnumerable GetDefaultTriggers() { var trigger = new DailyTrigger { TimeOfDay = TimeSpan.FromHours(0) }; //12am @@ -41,7 +52,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// The cancellation token. /// The progress. /// Task. - protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress progress) + public Task Execute(CancellationToken cancellationToken, IProgress progress) { cancellationToken.ThrowIfCancellationRequested(); @@ -54,7 +65,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// Gets the name. /// /// The name. - 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. /// /// The description. - public override string Description + public string Description { get { return "Moves logging to a new file to help reduce log file sizes."; } } + + /// + /// Gets the category. + /// + /// The category. + 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 a101ad3dd4..18fcdbbda9 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs @@ -11,31 +11,42 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// /// Plugin Update Task /// - public class SystemUpdateTask : BaseScheduledTask + public class SystemUpdateTask : IScheduledTask { /// /// The _app host /// private readonly IApplicationHost _appHost; + /// + /// Gets or sets the kernel. + /// + /// The kernel. + private IKernel Kernel { get; set; } + /// + /// Gets or sets the logger. + /// + /// The logger. + private ILogger Logger { get; set; } + /// /// Initializes a new instance of the class. /// /// The app host. - /// The task manager. /// The kernel. /// The logger. - 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; } /// /// Creates the triggers that define when the task will run /// /// IEnumerable{BaseTaskTrigger}. - public override IEnumerable GetDefaultTriggers() + public IEnumerable GetDefaultTriggers() { return new ITaskTrigger[] { @@ -52,7 +63,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// The cancellation token. /// The progress. /// Task. - protected override async Task ExecuteInternal(CancellationToken cancellationToken, IProgress progress) + public async Task Execute(CancellationToken cancellationToken, IProgress progress) { if (!_appHost.CanSelfUpdate) return; @@ -105,7 +116,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// Gets the name of the task /// /// The name. - 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. /// /// The description. - public override string Description + public string Description { get { return "Downloads and installs application updates."; } } + + /// + /// Gets the category. + /// + /// The category. + public string Category + { + get { return "Application"; } + } } } diff --git a/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs index bc8935a86c..4a6b9255c1 100644 --- a/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs +++ b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs @@ -17,12 +17,10 @@ namespace MediaBrowser.Common.Implementations.Serialization /// /// Serializes to stream. /// - /// /// The obj. /// The stream. /// obj - public void SerializeToStream(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 /// /// Serializes to file. /// - /// /// The obj. /// The file. /// obj - public void SerializeToFile(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 /// /// Serializes to string. /// - /// /// The obj. /// System.String. /// obj - public string SerializeToString(T obj) - where T : class + public string SerializeToString(object obj) { if (obj == null) { @@ -218,12 +212,10 @@ namespace MediaBrowser.Common.Implementations.Serialization /// /// Serializes to bytes. /// - /// /// The obj. /// System.Byte[][]. /// obj - public byte[] SerializeToBytes(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 14eb42cace..63fd0052fc 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -2,4 +2,5 @@ + \ No newline at end of file diff --git a/MediaBrowser.Common/Kernel/BaseKernel.cs b/MediaBrowser.Common/Kernel/BaseKernel.cs index eb5381e206..5b8da5d094 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 @@ -140,12 +137,6 @@ namespace MediaBrowser.Common.Kernel } } - /// - /// Gets a value indicating whether this instance is first run. - /// - /// true if this instance is first run; otherwise, false. - public bool IsFirstRun { get; private set; } - /// /// Gets or sets a value indicating whether this instance has changes that require the entire application to restart. /// @@ -176,12 +167,6 @@ namespace MediaBrowser.Common.Kernel /// The TCP manager. public TcpManager TcpManager { get; private set; } - /// - /// Gets the rest services. - /// - /// The rest services. - public IEnumerable RestServices { get; private set; } - /// /// 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. @@ -280,19 +265,7 @@ namespace MediaBrowser.Common.Kernel /// Initializes the Kernel /// /// Task. - public Task Init() - { - IsFirstRun = !File.Exists(ApplicationPaths.SystemConfigurationFilePath); - - // Performs initializations that can be reloaded at anytime - return Reload(); - } - - /// - /// Performs initializations that can be reloaded at anytime - /// - /// Task. - 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 /// protected virtual void FindParts() { - RestServices = ApplicationHost.GetExports(); WebSocketListeners = ApplicationHost.GetExports(); Plugins = ApplicationHost.GetExports(); } @@ -425,18 +395,6 @@ namespace MediaBrowser.Common.Kernel } } - /// - /// Gets the current application version - /// - /// The application version. - public Version ApplicationVersion - { - get - { - return GetType().Assembly.GetName().Version; - } - } - /// /// Performs the pending restart. /// @@ -445,7 +403,9 @@ namespace MediaBrowser.Common.Kernel { if (HasPendingRestart) { - RestartApplication(); + Logger.Info("Restarting the application"); + + ApplicationHost.Restart(); } else { @@ -453,16 +413,6 @@ namespace MediaBrowser.Common.Kernel } } - /// - /// Restarts the application. - /// - protected void RestartApplication() - { - Logger.Info("Restarting the application"); - - ApplicationHost.Restart(); - } - /// /// Gets the system status. /// @@ -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 4b564581b4..af9b039bc0 100644 --- a/MediaBrowser.Common/Kernel/IApplicationHost.cs +++ b/MediaBrowser.Common/Kernel/IApplicationHost.cs @@ -21,6 +21,12 @@ namespace MediaBrowser.Common.Kernel /// void ReloadLogger(); + /// + /// Gets the application version. + /// + /// The application version. + Version ApplicationVersion { get; } + /// /// Gets the log file path. /// @@ -33,11 +39,17 @@ namespace MediaBrowser.Common.Kernel /// true if this instance can self update; otherwise, false. bool CanSelfUpdate { get; } + /// + /// Gets a value indicating whether this instance is first run. + /// + /// true if this instance is first run; otherwise, false. + bool IsFirstRun { get; } + /// /// Gets the failed assemblies. /// /// The failed assemblies. - IEnumerable FailedAssemblies { get; } + List FailedAssemblies { get; } /// /// Gets all concrete types. @@ -72,34 +84,6 @@ namespace MediaBrowser.Common.Kernel /// System.Object. object CreateInstance(Type type); - /// - /// Registers a service that other classes can use as a dependancy. - /// - /// - /// The obj. - void RegisterSingleInstance(T obj) where T : class; - - /// - /// Registers the single instance. - /// - /// - /// The func. - void RegisterSingleInstance(Func func) where T : class; - - /// - /// Registers the specified func. - /// - /// - /// The func. - void Register(Func func) where T : class; - - /// - /// Registers the specified service type. - /// - /// Type of the service. - /// Type of the implementation. - void Register(Type serviceType, Type implementation); - /// /// Resolves this instance. /// diff --git a/MediaBrowser.Common/Kernel/IKernel.cs b/MediaBrowser.Common/Kernel/IKernel.cs index fb629a24df..06c2e7b64c 100644 --- a/MediaBrowser.Common/Kernel/IKernel.cs +++ b/MediaBrowser.Common/Kernel/IKernel.cs @@ -37,12 +37,6 @@ namespace MediaBrowser.Common.Kernel /// Task. Task Init(); - /// - /// Reloads this instance. - /// - /// Task. - Task Reload(); - /// /// Gets or sets a value indicating whether this instance has pending kernel reload. /// @@ -106,12 +100,6 @@ namespace MediaBrowser.Common.Kernel /// The HTTP server URL prefix. string HttpServerUrlPrefix { get; } - /// - /// Gets a value indicating whether this instance is first run. - /// - /// true if this instance is first run; otherwise, false. - bool IsFirstRun { get; } - /// /// Gets the TCP manager. /// @@ -139,12 +127,6 @@ namespace MediaBrowser.Common.Kernel /// event EventHandler ConfigurationUpdated; - /// - /// Gets the rest services. - /// - /// The rest services. - IEnumerable RestServices { get; } - /// /// Notifies the pending restart. /// diff --git a/MediaBrowser.Common/Kernel/TcpManager.cs b/MediaBrowser.Common/Kernel/TcpManager.cs index 1c76b42f96..2dfed501af 100644 --- a/MediaBrowser.Common/Kernel/TcpManager.cs +++ b/MediaBrowser.Common/Kernel/TcpManager.cs @@ -39,7 +39,7 @@ namespace MediaBrowser.Common.Kernel /// /// The json serializer. private readonly IJsonSerializer _jsonSerializer; - + /// /// This subscribes to HttpListener requests and finds the appropriate BaseHandler to process it /// @@ -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 /// The instance containing the event data. 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 bc3678a5e2..333c20beb7 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -95,8 +95,6 @@ - - @@ -122,6 +120,8 @@ True Resources.resx + + @@ -130,13 +130,10 @@ - - - diff --git a/MediaBrowser.Common/Net/Handlers/BaseActionHandler.cs b/MediaBrowser.Common/Net/Handlers/BaseActionHandler.cs deleted file mode 100644 index 72df88519b..0000000000 --- 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 -{ - /// - /// Class BaseActionHandler - /// - /// The type of the T kernel type. - public abstract class BaseActionHandler : BaseSerializationHandler - where TKernelType : IKernel - { - /// - /// Gets the object to serialize. - /// - /// Task{EmptyRequestResult}. - protected override async Task GetObjectToSerialize() - { - await ExecuteAction(); - - return new EmptyRequestResult(); - } - - /// - /// Performs the action. - /// - /// Task. - 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 a00152d784..0000000000 --- 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 -{ - /// - /// Class BaseSerializationHandler - /// - /// The type of the T kernel type. - /// - public abstract class BaseSerializationHandler : BaseHandler - where TKernelType : IKernel - where T : class - { - /// - /// Gets the serialization format. - /// - /// The serialization format. - public SerializationFormat SerializationFormat - { - get - { - var format = QueryString["dataformat"]; - - if (string.IsNullOrEmpty(format)) - { - return SerializationFormat.Json; - } - - return (SerializationFormat)Enum.Parse(typeof(SerializationFormat), format, true); - } - } - - /// - /// Gets the type of the content. - /// - /// The type of the content. - protected string ContentType - { - get - { - switch (SerializationFormat) - { - case SerializationFormat.Protobuf: - return "application/x-protobuf"; - default: - return MimeTypes.JsonMimeType; - } - } - } - - /// - /// Gets the response info. - /// - /// Task{ResponseInfo}. - protected override Task GetResponseInfo() - { - return Task.FromResult(new ResponseInfo - { - ContentType = ContentType - }); - } - - /// - /// Called when [processing request]. - /// - /// The response info. - /// Task. - protected override async Task OnProcessingRequest(ResponseInfo responseInfo) - { - _objectToSerialize = await GetObjectToSerialize().ConfigureAwait(false); - - if (_objectToSerialize == null) - { - throw new ResourceNotFoundException(); - } - - await base.OnProcessingRequest(responseInfo).ConfigureAwait(false); - } - - /// - /// The _object to serialize - /// - private T _objectToSerialize; - - /// - /// Gets the object to serialize. - /// - /// Task{`0}. - protected abstract Task GetObjectToSerialize(); - - /// - /// Writes the response to output stream. - /// - /// The stream. - /// The response info. - /// Length of the content. - /// Task. - 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; - //} - }); - } - } - - /// - /// Enum SerializationFormat - /// - public enum SerializationFormat - { - /// - /// The json - /// - Json, - /// - /// The protobuf - /// - Protobuf - } -} diff --git a/MediaBrowser.Common/Net/IHttpClient.cs b/MediaBrowser.Common/Net/IHttpClient.cs index ef0dd69b70..d02f08572d 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 { + /// + /// Interface IHttpClient + /// public interface IHttpClient : IDisposable { /// @@ -52,10 +55,5 @@ namespace MediaBrowser.Common.Net /// Task{MemoryStream}. /// Task GetMemoryStream(string url, SemaphoreSlim resourcePool, CancellationToken cancellationToken); - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - void Dispose(); } } \ No newline at end of file diff --git a/MediaBrowser.Common/Net/IHttpServer.cs b/MediaBrowser.Common/Net/IHttpServer.cs index a640fb2626..45da18e1b8 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]. /// event EventHandler WebSocketConnected; + + /// + /// Inits this instance. + /// + void Init(IEnumerable services); } } \ No newline at end of file diff --git a/MediaBrowser.Common/Net/IRestfulService.cs b/MediaBrowser.Common/Net/IRestfulService.cs index 7fc6bb61ec..36055cd8a3 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 /// 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 36d649e3b1..1ad0e8f06f 100644 --- a/MediaBrowser.Common/Net/WebSocketConnection.cs +++ b/MediaBrowser.Common/Net/WebSocketConnection.cs @@ -41,17 +41,22 @@ namespace MediaBrowser.Common.Net /// The _json serializer /// private readonly IJsonSerializer _jsonSerializer; - + + /// + /// Gets or sets the receive action. + /// + /// The receive action. + public Action OnReceive { get; set; } + /// /// Initializes a new instance of the class. /// /// The socket. /// The remote end point. - /// The receive action. /// The json serializer. /// The logger. /// socket - public WebSocketConnection(IWebSocket socket, string remoteEndPoint, Action 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]. /// /// The bytes. - /// The callback. - private void OnReceive(byte[] bytes, Action callback) + private void OnReceiveInternal(byte[] bytes) { + if (OnReceive == null) + { + return; + } try { WebSocketMessageInfo info; using (var memoryStream = new MemoryStream(bytes)) { - info = _jsonSerializer.DeserializeFromStream(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 dad3867fcb..72c83a5cee 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); } /// diff --git a/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs b/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs index 6f3a3857fe..351e96c7d5 100644 --- a/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs +++ b/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs @@ -1,39 +1,15 @@ -using MediaBrowser.Model.Tasks; -using System; +using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Common.ScheduledTasks { /// - /// Interface IScheduledTask + /// Interface IScheduledTaskWorker /// - public interface IScheduledTask : IDisposable + public interface IScheduledTask { - /// - /// Gets the triggers. - /// - /// The triggers. - IEnumerable Triggers { get; set; } - - /// - /// Gets the last execution result. - /// - /// The last execution result. - TaskResult LastExecutionResult { get; } - - /// - /// Gets the state. - /// - /// The state. - TaskState State { get; } - - /// - /// Gets the current progress. - /// - /// The current progress. - double? CurrentProgress { get; } - /// /// Gets the name of the task /// @@ -52,29 +28,13 @@ namespace MediaBrowser.Common.ScheduledTasks /// The category. string Category { get; } - /// - /// Gets the unique id. - /// - /// The unique id. - Guid Id { get; } - /// /// Executes the task /// + /// The cancellation token. + /// The progress. /// Task. - /// Cannot execute a Task that is already running - Task Execute(); - - /// - /// Stops the task if it is currently executing - /// - /// Cannot cancel a Task unless it is in the Running state. - void Cancel(); - - /// - /// Cancels if running. - /// - void CancelIfRunning(); + Task Execute(CancellationToken cancellationToken, IProgress progress); /// /// Gets the default triggers. @@ -82,4 +42,4 @@ namespace MediaBrowser.Common.ScheduledTasks /// IEnumerable{BaseTaskTrigger}. IEnumerable 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 0000000000..31cb4bcb89 --- /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 +{ + /// + /// Interface IScheduledTaskWorker + /// + public interface IScheduledTaskWorker : IDisposable + { + /// + /// Gets or sets the scheduled task. + /// + /// The scheduled task. + IScheduledTask ScheduledTask { get; } + + /// + /// Gets the last execution result. + /// + /// The last execution result. + TaskResult LastExecutionResult { get; } + + /// + /// Gets the name. + /// + /// The name. + string Name { get; } + + /// + /// Gets the description. + /// + /// The description. + string Description { get; } + + /// + /// Gets the category. + /// + /// The category. + string Category { get; } + + /// + /// Gets the state. + /// + /// The state. + TaskState State { get; } + + /// + /// Gets the current progress. + /// + /// The current progress. + double? CurrentProgress { get; } + + /// + /// Gets the triggers that define when the task will run + /// + /// The triggers. + /// value + IEnumerable Triggers { get; set; } + + /// + /// Gets the unique id. + /// + /// The unique id. + Guid Id { get; } + + /// + /// Executes the task + /// + /// Task. + /// Cannot execute a Task that is already running + Task Execute(); + + /// + /// Stops the task if it is currently executing + /// + /// Cannot cancel a Task unless it is in the Running state. + void Cancel(); + + /// + /// Cancels if running. + /// + void CancelIfRunning(); + } +} \ No newline at end of file diff --git a/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs b/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs index 42d7020e60..d06f1f1946 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 /// /// The scheduled tasks. - IScheduledTask[] ScheduledTasks { get; } + IScheduledTaskWorker[] ScheduledTasks { get; } /// /// Cancels if running and queue. @@ -37,35 +36,5 @@ namespace MediaBrowser.Common.ScheduledTasks /// /// The tasks. void AddTasks(IEnumerable tasks); - - /// - /// Called when [task completed]. - /// - /// The task. - /// The start time. - /// The end time. - /// The status. - void OnTaskCompleted(IScheduledTask task, DateTime startTime, DateTime endTime, TaskCompletionStatus status); - - /// - /// Gets the last execution result. - /// - /// The task. - /// TaskResult. - TaskResult GetLastExecutionResult(IScheduledTask task); - - /// - /// Loads the triggers. - /// - /// The task. - /// IEnumerable{BaseTaskTrigger}. - IEnumerable LoadTriggers(IScheduledTask task); - - /// - /// Saves the triggers. - /// - /// The task. - /// The triggers. - void SaveTriggers(IScheduledTask task, IEnumerable triggers); } } \ No newline at end of file diff --git a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs b/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs index 2c3d21a4b0..ebfc94591e 100644 --- a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs +++ b/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Common.ScheduledTasks /// /// The task. /// TaskInfo. - 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 1e901055ef..ff2bcb213f 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -132,7 +132,6 @@ - @@ -179,10 +178,7 @@ - - - diff --git a/MediaBrowser.Controller/Plugins/PluginSecurityManager.cs b/MediaBrowser.Controller/Plugins/PluginSecurityManager.cs index a08eb457d4..db3f20ee3f 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 } } - /// - /// The _network manager - /// - private INetworkManager _networkManager; + private IHttpClient _httpClient; + private IJsonSerializer _jsonSerializer; /// /// The _kernel @@ -53,21 +52,22 @@ namespace MediaBrowser.Controller.Plugins /// Initializes a new instance of the class. /// /// The kernel. - /// The network manager. - 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); } /// @@ -78,7 +78,7 @@ namespace MediaBrowser.Controller.Plugins /// Task{MBRegistrationRecord}. public async Task GetRegistrationStatus(string feature, string mb2Equivalent = null) { - return await MBRegistration.GetRegistrationStatus(feature, mb2Equivalent).ConfigureAwait(false); + return await MBRegistration.GetRegistrationStatus(_httpClient, _jsonSerializer, feature, mb2Equivalent).ConfigureAwait(false); } /// diff --git a/MediaBrowser.Controller/ScheduledTasks/PeopleValidationTask.cs b/MediaBrowser.Controller/ScheduledTasks/PeopleValidationTask.cs index 595de684da..4448b74397 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 /// /// Class PeopleValidationTask /// - public class PeopleValidationTask : BaseScheduledTask + public class PeopleValidationTask : IScheduledTask { + private readonly Kernel _kernel; + /// /// Initializes a new instance of the class. /// /// The kernel. - /// - public PeopleValidationTask(Kernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + public PeopleValidationTask(Kernel kernel) { + _kernel = kernel; } /// /// Creates the triggers that define when the task will run /// /// IEnumerable{BaseTaskTrigger}. - public override IEnumerable GetDefaultTriggers() + public IEnumerable GetDefaultTriggers() { return new ITaskTrigger[] { @@ -42,16 +42,16 @@ namespace MediaBrowser.Controller.ScheduledTasks /// The cancellation token. /// The progress. /// Task. - protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress progress) + public Task Execute(CancellationToken cancellationToken, IProgress progress) { - return Kernel.LibraryManager.ValidatePeople(cancellationToken, progress); + return _kernel.LibraryManager.ValidatePeople(cancellationToken, progress); } /// /// Gets the name of the task /// /// The name. - public override string Name + public string Name { get { return "Refresh people"; } } @@ -60,7 +60,7 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the description. /// /// The description. - 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. /// /// The category. - public override string Category + public string Category { get { diff --git a/MediaBrowser.Controller/ScheduledTasks/RefreshMediaLibraryTask.cs b/MediaBrowser.Controller/ScheduledTasks/RefreshMediaLibraryTask.cs index 104b432f4c..c5e36afb8f 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 /// /// Class RefreshMediaLibraryTask /// - public class RefreshMediaLibraryTask : BaseScheduledTask + public class RefreshMediaLibraryTask : IScheduledTask { + /// + /// The _kernel + /// + private readonly Kernel _kernel; + /// /// Initializes a new instance of the class. /// /// The kernel. - /// - public RefreshMediaLibraryTask(Kernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + public RefreshMediaLibraryTask(Kernel kernel) { + _kernel = kernel; } /// /// Gets the default triggers. /// /// IEnumerable{BaseTaskTrigger}. - public override IEnumerable GetDefaultTriggers() + public IEnumerable GetDefaultTriggers() { return new ITaskTrigger[] { @@ -45,20 +48,20 @@ namespace MediaBrowser.Controller.ScheduledTasks /// The cancellation token. /// The progress. /// Task. - protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress progress) + public Task Execute(CancellationToken cancellationToken, IProgress progress) { cancellationToken.ThrowIfCancellationRequested(); progress.Report(0); - return Kernel.LibraryManager.ValidateMediaLibrary(progress, cancellationToken); + return _kernel.LibraryManager.ValidateMediaLibrary(progress, cancellationToken); } /// /// Gets the name. /// /// The name. - public override string Name + public string Name { get { return "Scan media library"; } } @@ -67,7 +70,7 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the description. /// /// The description. - 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. /// /// The category. - public override string Category + public string Category { get { diff --git a/MediaBrowser.Controller/Updates/InstallationManager.cs b/MediaBrowser.Controller/Updates/InstallationManager.cs index 15d626b2fc..8751bd4274 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; @@ -119,6 +120,12 @@ namespace MediaBrowser.Controller.Updates /// The HTTP client. protected IHttpClient HttpClient { get; private set; } + /// + /// Gets the application host. + /// + /// The application host. + protected IApplicationHost ApplicationHost { get; private set; } + /// /// Initializes a new instance of the class. /// @@ -128,8 +135,9 @@ namespace MediaBrowser.Controller.Updates /// The network manager. /// The json serializer. /// The logger. + /// The app host. /// zipClient - 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)); } /// diff --git a/MediaBrowser.Model/Serialization/IJsonSerializer.cs b/MediaBrowser.Model/Serialization/IJsonSerializer.cs index 056389d2e5..77a14c1e5d 100644 --- a/MediaBrowser.Model/Serialization/IJsonSerializer.cs +++ b/MediaBrowser.Model/Serialization/IJsonSerializer.cs @@ -8,22 +8,18 @@ namespace MediaBrowser.Model.Serialization /// /// Serializes to stream. /// - /// /// The obj. /// The stream. /// obj - void SerializeToStream(T obj, Stream stream) - where T : class; + void SerializeToStream(object obj, Stream stream); /// /// Serializes to file. /// - /// /// The obj. /// The file. /// obj - void SerializeToFile(T obj, string file) - where T : class; + void SerializeToFile(object obj, string file); /// /// Deserializes from file. @@ -83,21 +79,17 @@ namespace MediaBrowser.Model.Serialization /// /// Serializes to string. /// - /// /// The obj. /// System.String. /// obj - string SerializeToString(T obj) - where T : class; + string SerializeToString(object obj); /// /// Serializes to bytes. /// - /// /// The obj. /// System.Byte[][]. /// obj - byte[] SerializeToBytes(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 similarity index 98% rename from MediaBrowser.Common/Net/BaseRestService.cs rename to MediaBrowser.Networking/HttpServer/BaseRestService.cs index a7e95fca2f..d499f07814 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 { /// /// Class BaseRestService @@ -45,14 +48,6 @@ namespace MediaBrowser.Common.Net } } - /// - /// Adds the routes. - /// - /// The app host. - public virtual void Configure(IAppHost appHost) - { - } - /// /// To the optimized result. /// diff --git a/MediaBrowser.Networking/HttpServer/HttpServer.cs b/MediaBrowser.Networking/HttpServer/HttpServer.cs index b6250527db..08a6b3561e 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; } /// - /// Gets or sets the kernel. + /// The _rest services /// - /// The kernel. - private IKernel Kernel { get; set; } + private readonly List _restServices = new List(); /// /// Gets or sets the application host. @@ -88,19 +88,14 @@ namespace MediaBrowser.Networking.HttpServer /// Initializes a new instance of the class. /// /// The application host. - /// The kernel. /// The protobuf serializer. /// The logger. /// Name of the server. /// The default redirectpath. /// urlPrefix - 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(); } /// @@ -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 /// ServiceManager. 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 /// /// true if [enable HTTP request logging]; otherwise, false. public bool EnableHttpRequestLogging { get; set; } + + /// + /// Adds the rest handlers. + /// + /// The services. + public void Init(IEnumerable 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(); + } } /// diff --git a/MediaBrowser.Networking/HttpServer/ServerFactory.cs b/MediaBrowser.Networking/HttpServer/ServerFactory.cs index e853a6ec22..716fd450a5 100644 --- a/MediaBrowser.Networking/HttpServer/ServerFactory.cs +++ b/MediaBrowser.Networking/HttpServer/ServerFactory.cs @@ -14,15 +14,14 @@ namespace MediaBrowser.Networking.HttpServer /// Creates the server. /// /// The application host. - /// The kernel. /// The protobuf serializer. /// The logger. /// Name of the server. /// The default redirectpath. /// IHttpServer. - 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 7bb3fc930d..3ef7832dfc 100644 --- a/MediaBrowser.Networking/MediaBrowser.Networking.csproj +++ b/MediaBrowser.Networking/MediaBrowser.Networking.csproj @@ -107,6 +107,7 @@ Properties\SharedVersion.cs + diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 416a7d7464..ec29ca4d30 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -51,6 +51,10 @@ Properties\SharedVersion.cs + + + + diff --git a/MediaBrowser.Controller/Persistence/TypeMapper.cs b/MediaBrowser.Server.Implementations/Reflection/TypeMapper.cs similarity index 96% rename from MediaBrowser.Controller/Persistence/TypeMapper.cs rename to MediaBrowser.Server.Implementations/Reflection/TypeMapper.cs index 2b9ec9e5ec..5f411a0023 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 { /// /// Class TypeMapper diff --git a/MediaBrowser.Controller/ScheduledTasks/ChapterImagesTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs similarity index 69% rename from MediaBrowser.Controller/ScheduledTasks/ChapterImagesTask.cs rename to MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs index 5360337199..d3854f9d79 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 { /// /// Class ChapterImagesTask /// - class ChapterImagesTask : BaseScheduledTask + class ChapterImagesTask : IScheduledTask { + /// + /// The _kernel + /// + private readonly Kernel _kernel; + /// + /// The _logger + /// + private readonly ILogger _logger; + /// /// Initializes a new instance of the class. /// /// The kernel. - /// - public ChapterImagesTask(Kernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + /// The logger. + public ChapterImagesTask(Kernel kernel, ILogger logger) { + _kernel = kernel; + _logger = logger; } /// /// Creates the triggers that define when the task will run /// /// IEnumerable{BaseTaskTrigger}. - public override IEnumerable GetDefaultTriggers() + public IEnumerable GetDefaultTriggers() { return new ITaskTrigger[] { @@ -42,9 +53,9 @@ namespace MediaBrowser.Controller.ScheduledTasks /// The cancellation token. /// The progress. /// Task. - protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress progress) + public Task Execute(CancellationToken cancellationToken, IProgress progress) { - var videos = Kernel.RootFolder.RecursiveChildren.OfType /// The name. - public override string Name + public string Name { get { return "Create video chapter thumbnails"; } } @@ -91,7 +102,7 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the description. /// /// The description. - 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. /// /// The category. - public override string Category + public string Category { get { diff --git a/MediaBrowser.Controller/ScheduledTasks/ImageCleanupTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/ImageCleanupTask.cs similarity index 80% rename from MediaBrowser.Controller/ScheduledTasks/ImageCleanupTask.cs rename to MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/ImageCleanupTask.cs index 7e0094a676..57f69e2e3f 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 { /// /// Class ImageCleanupTask /// - public class ImageCleanupTask : BaseScheduledTask + public class ImageCleanupTask : IScheduledTask { + /// + /// The _kernel + /// + private readonly Kernel _kernel; + /// + /// The _logger + /// + private readonly ILogger _logger; + /// /// Initializes a new instance of the class. /// /// The kernel. - /// The task manager. /// The logger. - public ImageCleanupTask(Kernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + public ImageCleanupTask(Kernel kernel, ILogger logger) { + _kernel = kernel; + _logger = logger; } /// /// Creates the triggers that define when the task will run /// /// IEnumerable{BaseTaskTrigger}. - public override IEnumerable GetDefaultTriggers() + public IEnumerable GetDefaultTriggers() { return new ITaskTrigger[] { @@ -45,19 +55,19 @@ namespace MediaBrowser.Controller.ScheduledTasks /// The cancellation token. /// The progress. /// Task. - protected override async Task ExecuteInternal(CancellationToken cancellationToken, IProgress progress) + public async Task Execute(CancellationToken cancellationToken, IProgress 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 /// Task. private Task EnsureChapterImages(CancellationToken cancellationToken) { - var videos = Kernel.RootFolder.RecursiveChildren.OfType /// The name. - public override string Name + public string Name { get { return "Images cleanup"; } } @@ -190,7 +200,7 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the description. /// /// The description. - 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. /// /// The category. - public override string Category + public string Category { get { diff --git a/MediaBrowser.Controller/ScheduledTasks/PluginUpdateTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs similarity index 71% rename from MediaBrowser.Controller/ScheduledTasks/PluginUpdateTask.cs rename to MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs index 7a1007f1bb..01a0458535 100644 --- a/MediaBrowser.Controller/ScheduledTasks/PluginUpdateTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs @@ -13,23 +13,33 @@ namespace MediaBrowser.Controller.ScheduledTasks /// /// Plugin Update Task /// - public class PluginUpdateTask : BaseScheduledTask + public class PluginUpdateTask : IScheduledTask { + /// + /// The _kernel + /// + private readonly Kernel _kernel; + /// + /// The _logger + /// + private readonly ILogger _logger; + /// /// Initializes a new instance of the class. /// /// The kernel. - /// - public PluginUpdateTask(Kernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + /// The logger. + public PluginUpdateTask(Kernel kernel, ILogger logger) { + _kernel = kernel; + _logger = logger; } /// /// Creates the triggers that define when the task will run /// /// IEnumerable{BaseTaskTrigger}. - public override IEnumerable GetDefaultTriggers() + public IEnumerable GetDefaultTriggers() { return new ITaskTrigger[] { @@ -46,11 +56,11 @@ namespace MediaBrowser.Controller.ScheduledTasks /// The cancellation token. /// The progress. /// Task. - protected override async Task ExecuteInternal(CancellationToken cancellationToken, IProgress progress) + public async Task Execute(CancellationToken cancellationToken, IProgress 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 { }, cancellationToken).ConfigureAwait(false); + await _kernel.InstallationManager.InstallPackage(i, new Progress { }, 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 /// /// The name. - public override string Name + public string Name { get { return "Check for plugin updates"; } } @@ -113,9 +123,14 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the description. /// /// The description. - 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 034cd21883..24de081f93 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 5808120adf..f6f70b382e 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 class. /// /// The logger. - public App(ILogger logger) + public App() { - Logger = logger; - InitializeComponent(); } @@ -174,13 +170,16 @@ namespace MediaBrowser.ServerApplication /// 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 5a98e7d93d..e862a394e5 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 /// /// Class CompositionRoot /// - public class ApplicationHost : IApplicationHost, IDisposable + public class ApplicationHost : BaseApplicationHost, IApplicationHost { - /// - /// Gets or sets the logger. - /// - /// The logger. - private ILogger Logger { get; set; } - /// /// Gets or sets the log file path. /// /// The log file path. public string LogFilePath { get; private set; } - /// - /// The container - /// - private readonly Container _container = new Container(); - /// /// Gets or sets the kernel. /// /// The kernel. - public Kernel Kernel { get; private set; } - - private readonly List _failedAssemblies = new List(); - /// - /// Gets assemblies that failed to load - /// - public IEnumerable FailedAssemblies - { - get { return _failedAssemblies; } - } - - /// - /// Gets all types within all running assemblies - /// - /// All types. - public Type[] AllTypes { get; private set; } - - /// - /// Gets all concrete types. - /// - /// All concrete types. - public Type[] AllConcreteTypes { get; private set; } - - /// - /// The disposable parts - /// - private readonly List _disposableParts = new List(); + internal Kernel Kernel { get; private set; } /// /// The json serializer @@ -107,20 +69,40 @@ namespace MediaBrowser.ServerApplication /// The _task manager /// private readonly ITaskManager _taskManager; - + + /// + /// The _task manager + /// + private readonly IHttpServer _httpServer; + + /// + /// Gets a value indicating whether this instance is first run. + /// + /// true if this instance is first run; otherwise, false. + public bool IsFirstRun { get; private set; } + /// /// Initializes a new instance of the class. /// /// The logger. - 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 /// /// Registers resources that classes will depend on /// - internal void RegisterResources() + private void RegisterResources() { - DiscoverTypes(); - RegisterSingleInstance(Kernel); RegisterSingleInstance(Kernel); - + RegisterSingleInstance(this); RegisterSingleInstance(Logger); RegisterSingleInstance(_applicationPaths); RegisterSingleInstance(_applicationPaths); RegisterSingleInstance(_taskManager); - RegisterSingleInstance(() => new PismoIsoManager(Logger)); - RegisterSingleInstance(() => new BdInfoExaminer()); - RegisterSingleInstance(() => new HttpManager(_applicationPaths, Logger)); - RegisterSingleInstance(() => new NetworkManager()); - RegisterSingleInstance(() => new DotNetZipClient()); + RegisterSingleInstance(new PismoIsoManager(Logger)); + RegisterSingleInstance(new BdInfoExaminer()); + RegisterSingleInstance(new HttpManager(_applicationPaths, Logger)); + RegisterSingleInstance(new NetworkManager()); + RegisterSingleInstance(new DotNetZipClient()); RegisterSingleInstance(() => new AlchemyServer(Logger)); RegisterSingleInstance(_jsonSerializer); RegisterSingleInstance(_xmlSerializer); - RegisterSingleInstance(() => ProtobufSerializer); - Register(typeof(IUdpServer), typeof(UdpServer)); - RegisterSingleInstance(() => ServerFactory.CreateServer(this, Kernel, ProtobufSerializer, Logger, "Media Browser", "index.html")); - } - - /// - /// Discovers the types. - /// - 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(new UdpServer()); + RegisterSingleInstance(_httpServer); } /// @@ -173,150 +141,8 @@ namespace MediaBrowser.ServerApplication private void FindParts() { _taskManager.AddTasks(GetExports(false)); - } - - /// - /// 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 - /// - /// The assembly. - /// IEnumerable{Type}. - /// assembly - private IEnumerable 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); - } - } - - /// - /// The _protobuf serializer initialized - /// - private bool _protobufSerializerInitialized; - /// - /// The _protobuf serializer sync lock - /// - private object _protobufSerializerSyncLock = new object(); - /// - /// Gets a dynamically compiled generated serializer that can serialize protocontracts without reflection - /// - private ProtobufSerializer _protobufSerializer; - /// - /// Gets the protobuf serializer. - /// - /// The protobuf serializer. - 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; - } - } - - /// - /// Creates an instance of type and resolves all constructor dependancies - /// - /// The type. - /// System.Object. - public object CreateInstance(Type type) - { - try - { - return _container.GetInstance(type); - } - catch - { - Logger.Error("Error creating {0}", type.Name); - throw; - } - } - - /// - /// Registers the specified obj. - /// - /// - /// The obj. - public void RegisterSingleInstance(T obj) - where T : class - { - _container.RegisterSingle(obj); - } - - /// - /// Registers the specified func. - /// - /// - /// The func. - public void Register(Func func) - where T : class - { - _container.Register(func); - } - - /// - /// Registers the single instance. - /// - /// - /// The func. - public void RegisterSingleInstance(Func func) - where T : class - { - _container.RegisterSingle(func); - } - - /// - /// Resolves this instance. - /// - /// - /// ``0. - public T Resolve() - { - return (T)_container.GetRegistration(typeof(T), true).GetInstance(); - } - - /// - /// Resolves this instance. - /// - /// - /// ``0. - public T TryResolve() - { - var result = _container.GetRegistration(typeof(T), false); - - if (result == null) - { - return default(T); - } - return (T)result.GetInstance(); - } - - /// - /// Registers the specified service type. - /// - /// Type of the service. - /// Type of the concrete. - public void Register(Type serviceType, Type implementation) - { - _container.Register(serviceType, implementation); + _httpServer.Init(GetExports(false)); } /// @@ -374,12 +200,12 @@ namespace MediaBrowser.ServerApplication /// Gets the composable part assemblies. /// /// IEnumerable{Assembly}. - private IEnumerable GetComposablePartAssemblies() + protected override IEnumerable 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; } - - /// - /// Loads the assembly. - /// - /// The file. - /// Assembly. - 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; - } - } - - /// - /// Gets the exports. - /// - /// - /// All types. - /// if set to true [manage liftime]. - /// IEnumerable{``0}. - public IEnumerable GetExports(bool manageLiftime = true) - { - var currentType = typeof(T); - - Logger.Info("Composing instances of " + currentType.Name); - - var parts = AllConcreteTypes.Where(currentType.IsAssignableFrom).Select(CreateInstance).Cast().ToArray(); - - if (manageLiftime) - { - _disposableParts.AddRange(parts.OfType()); - } - - return parts; - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - 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 59961a9418..cb5c62ff08 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 /// /// Initializes a new instance of the class. /// - 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 332bb1daa9..fc0f0efc9b 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; @@ -49,12 +50,19 @@ namespace MediaBrowser.ServerApplication /// private readonly ILogger _logger; + /// + /// The _app host + /// + private readonly IApplicationHost _appHost; + /// /// Initializes a new instance of the class. /// + /// The json serializer. /// The logger. + /// The app host. /// logger - 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 /// The instance containing the event data. private void cmOpenExplorer_click(object sender, RoutedEventArgs e) { - (new LibraryExplorer(_jsonSerializer, _logger)).Show(); + (new LibraryExplorer(_jsonSerializer, _logger, _appHost)).Show(); } /// diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index c843242c32..50cb0be6ca 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -128,6 +128,18 @@ False ..\ThirdParty\UPnP\Libs\Platinum.Managed.dll + + False + ..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Common.dll + + + False + ..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Interfaces.dll + + + False + ..\packages\ServiceStack.Text.3.9.37\lib\net35\ServiceStack.Text.dll + False ..\packages\SimpleInjector.2.0.0-beta5\lib\net40-client\SimpleInjector.dll diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index e1beae6da2..71e2844fc1 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -3,6 +3,8 @@ + + \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index b321cc8d9c..94cc37b314 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 /// /// Class GetDashboardResource /// + [Route("/dashboard/{name*}", "GET")] public class GetDashboardResource { /// @@ -91,17 +92,6 @@ namespace MediaBrowser.WebDashboard.Api { _taskManager = taskManager; } - - /// - /// Adds the routes. - /// - /// The app host. - public override void Configure(IAppHost appHost) - { - base.Configure(appHost); - - appHost.Routes.Add("/dashboard/{name*}", "GET"); - } /// /// 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 85efe04f18..a65a2afebb 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -99,6 +99,10 @@ {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} MediaBrowser.Model + + {7c11010e-179a-49b7-bfb2-f1656f5e71ad} + MediaBrowser.Networking + diff --git a/Nuget/MediaBrowser.ApiClient.nuspec b/Nuget/MediaBrowser.ApiClient.nuspec index 38f51a5cb5..3d6ec3a31c 100644 --- a/Nuget/MediaBrowser.ApiClient.nuspec +++ b/Nuget/MediaBrowser.ApiClient.nuspec @@ -11,14 +11,12 @@ Copyright © Media Browser 2013 - - + -