aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MediaBrowser.Api/Javascript/ApiClient.js (renamed from MediaBrowser.ApiInteraction.Javascript/ApiClient.js)0
-rw-r--r--MediaBrowser.Api/Javascript/JavascriptApiClientService.cs (renamed from MediaBrowser.ApiInteraction.Javascript/JavascriptApiClientService.cs)6
-rw-r--r--MediaBrowser.Api/LibraryService.cs25
-rw-r--r--MediaBrowser.Api/MediaBrowser.Api.csproj2
-rw-r--r--MediaBrowser.Api/PluginService.cs29
-rw-r--r--MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs33
-rw-r--r--MediaBrowser.Api/SystemService.cs35
-rw-r--r--MediaBrowser.Api/UserLibrary/UserLibraryService.cs65
-rw-r--r--MediaBrowser.Api/UserService.cs45
-rw-r--r--MediaBrowser.ApiInteraction.Javascript/MediaBrowser.ApiInteraction.Javascript.csproj105
-rw-r--r--MediaBrowser.ApiInteraction.Javascript/Properties/AssemblyInfo.cs30
-rw-r--r--MediaBrowser.ApiInteraction.Javascript/packages.config8
-rw-r--r--MediaBrowser.Common.Implementations/BaseApplicationPaths.cs (renamed from MediaBrowser.Common/Kernel/BaseApplicationPaths.cs)2
-rw-r--r--MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj (renamed from MediaBrowser.Server.WorldWeatherOnline/MediaBrowser.Server.WorldWeatherOnline.csproj)43
-rw-r--r--MediaBrowser.Common.Implementations/Properties/AssemblyInfo.cs (renamed from MediaBrowser.Server.Sqlite/Properties/AssemblyInfo.cs)8
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs322
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs (renamed from MediaBrowser.Common/ScheduledTasks/Tasks/DeleteCacheFileTask.cs)5
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs (renamed from MediaBrowser.Common/ScheduledTasks/Tasks/DeleteLogFileTask.cs)5
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs (renamed from MediaBrowser.Common/ScheduledTasks/Tasks/ReloadLoggerTask.cs)5
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs (renamed from MediaBrowser.Common/ScheduledTasks/Tasks/SystemUpdateTask.cs)7
-rw-r--r--MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs (renamed from MediaBrowser.Common/Serialization/JsonSerializer.cs)65
-rw-r--r--MediaBrowser.Common.Implementations/Serialization/ProtobufSerializer.cs (renamed from MediaBrowser.Common/Serialization/DynamicProtobufSerializer.cs)13
-rw-r--r--MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs (renamed from MediaBrowser.Common/Serialization/XmlSerializer.cs)96
-rw-r--r--MediaBrowser.Common.Implementations/packages.config5
-rw-r--r--MediaBrowser.Common/Kernel/BaseKernel.cs379
-rw-r--r--MediaBrowser.Common/Kernel/IApplicationHost.cs21
-rw-r--r--MediaBrowser.Common/Kernel/IApplicationPaths.cs76
-rw-r--r--MediaBrowser.Common/Kernel/IKernel.cs17
-rw-r--r--MediaBrowser.Common/Kernel/TcpManager.cs21
-rw-r--r--MediaBrowser.Common/MediaBrowser.Common.csproj19
-rw-r--r--MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs19
-rw-r--r--MediaBrowser.Common/Net/IWebSocket.cs2
-rw-r--r--MediaBrowser.Common/Net/WebSocketConnection.cs33
-rw-r--r--MediaBrowser.Common/Plugins/BasePlugin.cs22
-rw-r--r--MediaBrowser.Common/Plugins/IPlugin.cs4
-rw-r--r--MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs140
-rw-r--r--MediaBrowser.Common/ScheduledTasks/BaseTaskTrigger.cs64
-rw-r--r--MediaBrowser.Common/ScheduledTasks/DailyTrigger.cs30
-rw-r--r--MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs8
-rw-r--r--MediaBrowser.Common/ScheduledTasks/ITaskManager.cs29
-rw-r--r--MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs26
-rw-r--r--MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs30
-rw-r--r--MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs4
-rw-r--r--MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs25
-rw-r--r--MediaBrowser.Common/ScheduledTasks/SystemEventTrigger.cs23
-rw-r--r--MediaBrowser.Common/ScheduledTasks/TaskManager.cs159
-rw-r--r--MediaBrowser.Common/ScheduledTasks/WeeklyTrigger.cs30
-rw-r--r--MediaBrowser.Common/packages.config1
-rw-r--r--MediaBrowser.Controller/Drawing/ImageManager.cs45
-rw-r--r--MediaBrowser.Controller/Entities/User.cs15
-rw-r--r--MediaBrowser.Controller/IServerApplicationPaths.cs85
-rw-r--r--MediaBrowser.Controller/Kernel.cs64
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj2
-rw-r--r--MediaBrowser.Controller/MediaInfo/FFMpegManager.cs79
-rw-r--r--MediaBrowser.Controller/Providers/MediaInfo/FFProbeVideoInfoProvider.cs30
-rw-r--r--MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs31
-rw-r--r--MediaBrowser.Controller/Providers/Movies/MovieProviderFromJson.cs8
-rw-r--r--MediaBrowser.Controller/Providers/Movies/PersonProviderFromJson.cs8
-rw-r--r--MediaBrowser.Controller/Providers/Movies/TmdbPersonProvider.cs29
-rw-r--r--MediaBrowser.Controller/ScheduledTasks/ChapterImagesTask.cs4
-rw-r--r--MediaBrowser.Controller/ScheduledTasks/ImageCleanupTask.cs7
-rw-r--r--MediaBrowser.Controller/ScheduledTasks/PeopleValidationTask.cs4
-rw-r--r--MediaBrowser.Controller/ScheduledTasks/PluginUpdateTask.cs4
-rw-r--r--MediaBrowser.Controller/ScheduledTasks/RefreshMediaLibraryTask.cs4
-rw-r--r--MediaBrowser.Controller/Updates/InstallationManager.cs46
-rw-r--r--MediaBrowser.Model/MediaBrowser.Model.csproj3
-rw-r--r--MediaBrowser.Model/Serialization/IJsonSerializer.cs103
-rw-r--r--MediaBrowser.Model/Serialization/IProtobufSerializer.cs63
-rw-r--r--MediaBrowser.Model/Serialization/IXmlSerializer.cs69
-rw-r--r--MediaBrowser.Networking/MediaBrowser.Networking.csproj2
-rw-r--r--MediaBrowser.Networking/Web/HttpServer.cs21
-rw-r--r--MediaBrowser.Networking/Web/NativeWebSocket.cs (renamed from MediaBrowser.Common/Net/NativeWebSocket.cs)20
-rw-r--r--MediaBrowser.Networking/Web/ServerFactory.cs28
-rw-r--r--MediaBrowser.Networking/WebSocket/AlchemyWebSocket.cs8
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj (renamed from MediaBrowser.Server.Sqlite/MediaBrowser.Server.Sqlite.csproj)56
-rw-r--r--MediaBrowser.Server.Implementations/Properties/AssemblyInfo.cs (renamed from MediaBrowser.Server.WorldWeatherOnline/Properties/AssemblyInfo.cs)9
-rw-r--r--MediaBrowser.Server.Implementations/ServerApplicationPaths.cs (renamed from MediaBrowser.Controller/ServerApplicationPaths.cs)7
-rw-r--r--MediaBrowser.Server.Implementations/Sqlite/SQLiteDisplayPreferencesRepository.cs (renamed from MediaBrowser.Server.Sqlite/SQLiteDisplayPreferencesRepository.cs)37
-rw-r--r--MediaBrowser.Server.Implementations/Sqlite/SQLiteExtensions.cs (renamed from MediaBrowser.Server.Sqlite/SQLiteExtensions.cs)2
-rw-r--r--MediaBrowser.Server.Implementations/Sqlite/SQLiteItemRepository.cs (renamed from MediaBrowser.Server.Sqlite/SQLiteItemRepository.cs)41
-rw-r--r--MediaBrowser.Server.Implementations/Sqlite/SQLiteRepository.cs (renamed from MediaBrowser.Server.Sqlite/SQLiteRepository.cs)2
-rw-r--r--MediaBrowser.Server.Implementations/Sqlite/SQLiteUserDataRepository.cs (renamed from MediaBrowser.Server.Sqlite/SQLiteUserDataRepository.cs)37
-rw-r--r--MediaBrowser.Server.Implementations/Sqlite/SQLiteUserRepository.cs (renamed from MediaBrowser.Server.Sqlite/SQLiteUserRepository.cs)41
-rw-r--r--MediaBrowser.Server.Implementations/WorldWeatherOnline/WeatherProvider.cs (renamed from MediaBrowser.Server.WorldWeatherOnline/WeatherProvider.cs)21
-rw-r--r--MediaBrowser.Server.Implementations/packages.config (renamed from MediaBrowser.Server.Sqlite/packages.config)0
-rw-r--r--MediaBrowser.ServerApplication/App.xaml.cs194
-rw-r--r--MediaBrowser.ServerApplication/ApplicationHost.cs498
-rw-r--r--MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs15
-rw-r--r--MediaBrowser.ServerApplication/MainWindow.xaml.cs15
-rw-r--r--MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj39
-rw-r--r--MediaBrowser.ServerApplication/packages.config5
-rw-r--r--MediaBrowser.WebDashboard/Api/DashboardService.cs3
-rw-r--r--MediaBrowser.sln81
93 files changed, 2450 insertions, 1576 deletions
diff --git a/MediaBrowser.ApiInteraction.Javascript/ApiClient.js b/MediaBrowser.Api/Javascript/ApiClient.js
index df1c8f2c0..df1c8f2c0 100644
--- a/MediaBrowser.ApiInteraction.Javascript/ApiClient.js
+++ b/MediaBrowser.Api/Javascript/ApiClient.js
diff --git a/MediaBrowser.ApiInteraction.Javascript/JavascriptApiClientService.cs b/MediaBrowser.Api/Javascript/JavascriptApiClientService.cs
index c03146e69..8c7499a7c 100644
--- a/MediaBrowser.ApiInteraction.Javascript/JavascriptApiClientService.cs
+++ b/MediaBrowser.Api/Javascript/JavascriptApiClientService.cs
@@ -5,13 +5,13 @@ using System;
using System.IO;
using System.Threading.Tasks;
-namespace MediaBrowser.ApiInteraction.Javascript
+namespace MediaBrowser.Api.Javascript
{
/// <summary>
/// Class GetJavascriptApiClient
/// </summary>
[Route("/JsApiClient.js", "GET")]
- [Api(("Gets an api wrapper in Javascript"))]
+ [ServiceStack.ServiceHost.Api(("Gets an api wrapper in Javascript"))]
public class GetJavascriptApiClient
{
/// <summary>
@@ -52,7 +52,7 @@ namespace MediaBrowser.ApiInteraction.Javascript
/// <returns>Stream.</returns>
private Task<Stream> GetStream()
{
- return Task.FromResult(GetType().Assembly.GetManifestResourceStream("MediaBrowser.ApiInteraction.Javascript.ApiClient.js"));
+ return Task.FromResult(GetType().Assembly.GetManifestResourceStream("MediaBrowser.Api.Javascript.ApiClient.js"));
}
}
}
diff --git a/MediaBrowser.Api/LibraryService.cs b/MediaBrowser.Api/LibraryService.cs
index 4ca073c10..434b04eff 100644
--- a/MediaBrowser.Api/LibraryService.cs
+++ b/MediaBrowser.Api/LibraryService.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Kernel;
+using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
@@ -98,6 +99,26 @@ namespace MediaBrowser.Api
public class LibraryService : BaseRestService
{
/// <summary>
+ /// The _app host
+ /// </summary>
+ private readonly IApplicationHost _appHost;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="LibraryService" /> class.
+ /// </summary>
+ /// <param name="appHost">The app host.</param>
+ /// <exception cref="System.ArgumentNullException">appHost</exception>
+ public LibraryService(IApplicationHost appHost)
+ {
+ if (appHost == null)
+ {
+ throw new ArgumentNullException("appHost");
+ }
+
+ _appHost = appHost;
+ }
+
+ /// <summary>
/// Gets the specified request.
/// </summary>
/// <param name="request">The request.</param>
@@ -210,7 +231,7 @@ namespace MediaBrowser.Api
{
var kernel = (Kernel)Kernel;
- var allTypes = kernel.AllTypes.Where(t => !t.IsAbstract && t.IsSubclassOf(typeof(BaseItem)));
+ var allTypes = _appHost.AllConcreteTypes.Where(t => t.IsSubclassOf(typeof(BaseItem)));
if (request.HasInternetProvider)
{
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index 9bdcdb650..c6c822624 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -80,6 +80,7 @@
<Compile Include="Images\ImageService.cs" />
<Compile Include="Images\ImageWriter.cs" />
<Compile Include="Images\UploadImageHandler.cs" />
+ <Compile Include="Javascript\JavascriptApiClientService.cs" />
<Compile Include="LibraryService.cs" />
<Compile Include="LocalizationService.cs" />
<Compile Include="PackageService.cs" />
@@ -128,6 +129,7 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
+ <EmbeddedResource Include="Javascript\ApiClient.js" />
<Content Include="options.xml" />
</ItemGroup>
<ItemGroup />
diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs
index f982602bf..1f906f814 100644
--- a/MediaBrowser.Api/PluginService.cs
+++ b/MediaBrowser.Api/PluginService.cs
@@ -1,15 +1,15 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Serialization;
using MediaBrowser.Controller;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Plugins;
+using MediaBrowser.Model.Serialization;
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
{
@@ -120,6 +120,27 @@ namespace MediaBrowser.Api
public class PluginService : BaseRestService
{
/// <summary>
+ /// The _json serializer
+ /// </summary>
+ private readonly IJsonSerializer _jsonSerializer;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PluginService" /> class.
+ /// </summary>
+ /// <param name="jsonSerializer">The json serializer.</param>
+ /// <exception cref="System.ArgumentNullException">jsonSerializer</exception>
+ public PluginService(IJsonSerializer jsonSerializer)
+ : base()
+ {
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
+
+ _jsonSerializer = jsonSerializer;
+ }
+
+ /// <summary>
/// Gets the specified request.
/// </summary>
/// <param name="request">The request.</param>
@@ -198,7 +219,7 @@ namespace MediaBrowser.Api
{
var kernel = (Kernel)Kernel;
- var info = JsonSerializer.DeserializeFromStream<PluginSecurityInfo>(request.RequestStream);
+ var info = _jsonSerializer.DeserializeFromStream<PluginSecurityInfo>(request.RequestStream);
kernel.PluginSecurityManager.SupporterKey = info.SupporterKey;
kernel.PluginSecurityManager.LegacyKey = info.LegacyKey;
@@ -217,7 +238,7 @@ namespace MediaBrowser.Api
var plugin = Kernel.Plugins.First(p => p.Id == id);
- var configuration = JsonSerializer.DeserializeFromStream(request.RequestStream, plugin.ConfigurationType) as BasePluginConfiguration;
+ var configuration = _jsonSerializer.DeserializeFromStream(request.RequestStream, plugin.ConfigurationType) as BasePluginConfiguration;
plugin.UpdateConfiguration(configuration);
}
diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
index 1ca744542..e79ab90da 100644
--- a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
+++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
@@ -1,7 +1,7 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Common.ScheduledTasks;
-using MediaBrowser.Common.Serialization;
+using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Tasks;
using ServiceStack.ServiceHost;
using System;
@@ -90,11 +90,32 @@ namespace MediaBrowser.Api.ScheduledTasks
/// <value>The task manager.</value>
private ITaskManager TaskManager { get; set; }
- public ScheduledTaskService(ITaskManager taskManager)
+ /// <summary>
+ /// The _json serializer
+ /// </summary>
+ private readonly IJsonSerializer _jsonSerializer;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ScheduledTaskService" /> class.
+ /// </summary>
+ /// <param name="taskManager">The task manager.</param>
+ /// <param name="jsonSerializer">The json serializer.</param>
+ /// <exception cref="System.ArgumentNullException">taskManager</exception>
+ public ScheduledTaskService(ITaskManager taskManager, IJsonSerializer jsonSerializer)
{
+ if (taskManager == null)
+ {
+ throw new ArgumentNullException("taskManager");
+ }
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
+
TaskManager = taskManager;
+ _jsonSerializer = jsonSerializer;
}
-
+
/// <summary>
/// Gets the specified request.
/// </summary>
@@ -113,6 +134,7 @@ namespace MediaBrowser.Api.ScheduledTasks
/// </summary>
/// <param name="request">The request.</param>
/// <returns>IEnumerable{TaskInfo}.</returns>
+ /// <exception cref="MediaBrowser.Common.Extensions.ResourceNotFoundException">Task not found</exception>
public object Get(GetScheduledTask request)
{
var task = TaskManager.ScheduledTasks.FirstOrDefault(i => i.Id == request.Id);
@@ -131,6 +153,7 @@ namespace MediaBrowser.Api.ScheduledTasks
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
+ /// <exception cref="MediaBrowser.Common.Extensions.ResourceNotFoundException">Task not found</exception>
public void Post(StartScheduledTask request)
{
var task = TaskManager.ScheduledTasks.FirstOrDefault(i => i.Id == request.Id);
@@ -147,6 +170,7 @@ namespace MediaBrowser.Api.ScheduledTasks
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
+ /// <exception cref="MediaBrowser.Common.Extensions.ResourceNotFoundException">Task not found</exception>
public void Delete(StopScheduledTask request)
{
var task = TaskManager.ScheduledTasks.FirstOrDefault(i => i.Id == request.Id);
@@ -163,6 +187,7 @@ namespace MediaBrowser.Api.ScheduledTasks
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
+ /// <exception cref="MediaBrowser.Common.Extensions.ResourceNotFoundException">Task not found</exception>
public void Post(UpdateScheduledTaskTriggers request)
{
// We need to parse this manually because we told service stack not to with IRequiresRequestStream
@@ -177,7 +202,7 @@ namespace MediaBrowser.Api.ScheduledTasks
throw new ResourceNotFoundException("Task not found");
}
- var triggerInfos = JsonSerializer.DeserializeFromStream<TaskTriggerInfo[]>(request.RequestStream);
+ var triggerInfos = _jsonSerializer.DeserializeFromStream<TaskTriggerInfo[]>(request.RequestStream);
task.Triggers = triggerInfos.Select(ScheduledTaskHelpers.GetTrigger);
}
diff --git a/MediaBrowser.Api/SystemService.cs b/MediaBrowser.Api/SystemService.cs
index 04632aa8e..7921d024a 100644
--- a/MediaBrowser.Api/SystemService.cs
+++ b/MediaBrowser.Api/SystemService.cs
@@ -1,15 +1,19 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Serialization;
using MediaBrowser.Controller;
using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.System;
using ServiceStack.ServiceHost;
+using System;
using System.IO;
using System.Threading.Tasks;
namespace MediaBrowser.Api
{
+ /// <summary>
+ /// Class GetSystemInfo
+ /// </summary>
[Route("/System/Info", "GET")]
public class GetSystemInfo : IReturn<SystemInfo>
{
@@ -40,6 +44,10 @@ namespace MediaBrowser.Api
[Route("/System/Configuration", "POST")]
public class UpdateConfiguration : IRequiresRequestStream
{
+ /// <summary>
+ /// The raw Http Request Input Stream
+ /// </summary>
+ /// <value>The request stream.</value>
public Stream RequestStream { get; set; }
}
@@ -49,6 +57,27 @@ namespace MediaBrowser.Api
public class SystemService : BaseRestService
{
/// <summary>
+ /// The _json serializer
+ /// </summary>
+ private readonly IJsonSerializer _jsonSerializer;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SystemService" /> class.
+ /// </summary>
+ /// <param name="jsonSerializer">The json serializer.</param>
+ /// <exception cref="System.ArgumentNullException">jsonSerializer</exception>
+ public SystemService(IJsonSerializer jsonSerializer)
+ : base()
+ {
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
+
+ _jsonSerializer = jsonSerializer;
+ }
+
+ /// <summary>
/// Gets the specified request.
/// </summary>
/// <param name="request">The request.</param>
@@ -95,8 +124,8 @@ namespace MediaBrowser.Api
/// <param name="request">The request.</param>
public void Post(UpdateConfiguration request)
{
- var serverConfig = JsonSerializer.DeserializeFromStream<ServerConfiguration>(request.RequestStream);
-
+ var serverConfig = _jsonSerializer.DeserializeFromStream<ServerConfiguration>(request.RequestStream);
+
var kernel = (Kernel)Kernel;
kernel.UpdateConfiguration(serverConfig);
diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index 576ff8892..4267947ad 100644
--- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
@@ -1,11 +1,11 @@
using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Serialization;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Serialization;
using ServiceStack.ServiceHost;
using System;
using System.Collections.Generic;
@@ -28,7 +28,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
public Guid UserId { get; set; }
-
+
/// <summary>
/// Gets or sets the id.
/// </summary>
@@ -48,7 +48,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
public Guid UserId { get; set; }
-
+
/// <summary>
/// Gets or sets the item id.
/// </summary>
@@ -68,7 +68,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
public Guid UserId { get; set; }
-
+
/// <summary>
/// Gets or sets the id.
/// </summary>
@@ -106,7 +106,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
public Guid UserId { get; set; }
-
+
/// <summary>
/// Gets or sets the id.
/// </summary>
@@ -125,7 +125,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
public Guid UserId { get; set; }
-
+
/// <summary>
/// Gets or sets the id.
/// </summary>
@@ -144,7 +144,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
public Guid UserId { get; set; }
-
+
/// <summary>
/// Gets or sets the id.
/// </summary>
@@ -163,7 +163,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
public Guid UserId { get; set; }
-
+
/// <summary>
/// Gets or sets the id.
/// </summary>
@@ -215,6 +215,9 @@ namespace MediaBrowser.Api.UserLibrary
public string Id { get; set; }
}
+ /// <summary>
+ /// Class GetLocalTrailers
+ /// </summary>
[Route("/Users/{UserId}/Items/{Id}/LocalTrailers", "GET")]
public class GetLocalTrailers : IReturn<List<BaseItemDto>>
{
@@ -231,6 +234,9 @@ namespace MediaBrowser.Api.UserLibrary
public string Id { get; set; }
}
+ /// <summary>
+ /// Class GetSpecialFeatures
+ /// </summary>
[Route("/Users/{UserId}/Items/{Id}/SpecialFeatures", "GET")]
public class GetSpecialFeatures : IReturn<List<BaseItemDto>>
{
@@ -253,6 +259,32 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
public class UserLibraryService : BaseRestService
{
+ /// <summary>
+ /// The _json serializer
+ /// </summary>
+ private readonly IJsonSerializer _jsonSerializer;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="UserLibraryService" /> class.
+ /// </summary>
+ /// <param name="jsonSerializer">The json serializer.</param>
+ /// <exception cref="System.ArgumentNullException">jsonSerializer</exception>
+ public UserLibraryService(IJsonSerializer jsonSerializer)
+ : base()
+ {
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
+
+ _jsonSerializer = jsonSerializer;
+ }
+
+ /// <summary>
+ /// Gets the specified request.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ /// <returns>System.Object.</returns>
public object Get(GetSpecialFeatures request)
{
var kernel = (Kernel)Kernel;
@@ -260,7 +292,7 @@ namespace MediaBrowser.Api.UserLibrary
var user = kernel.GetUserById(request.UserId);
var item = DtoBuilder.GetItemByClientId(request.Id, user.Id);
-
+
// Get everything
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
@@ -272,7 +304,12 @@ namespace MediaBrowser.Api.UserLibrary
return ToOptimizedResult(items);
}
-
+
+ /// <summary>
+ /// Gets the specified request.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ /// <returns>System.Object.</returns>
public object Get(GetLocalTrailers request)
{
var kernel = (Kernel)Kernel;
@@ -280,7 +317,7 @@ namespace MediaBrowser.Api.UserLibrary
var user = kernel.GetUserById(request.UserId);
var item = DtoBuilder.GetItemByClientId(request.Id, user.Id);
-
+
// Get everything
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
@@ -290,7 +327,7 @@ namespace MediaBrowser.Api.UserLibrary
return ToOptimizedResult(items);
}
-
+
/// <summary>
/// Gets the specified request.
/// </summary>
@@ -303,7 +340,7 @@ namespace MediaBrowser.Api.UserLibrary
var user = kernel.GetUserById(request.UserId);
var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, user.Id);
-
+
// Get everything
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
@@ -366,7 +403,7 @@ namespace MediaBrowser.Api.UserLibrary
var item = (Folder)DtoBuilder.GetItemByClientId(itemId, user.Id);
- var displayPreferences = JsonSerializer.DeserializeFromStream<DisplayPreferences>(request.RequestStream);
+ var displayPreferences = _jsonSerializer.DeserializeFromStream<DisplayPreferences>(request.RequestStream);
var task = kernel.LibraryManager.SaveDisplayPreferencesForFolder(user, item, displayPreferences);
diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs
index c76479d19..d4490d856 100644
--- a/MediaBrowser.Api/UserService.cs
+++ b/MediaBrowser.Api/UserService.cs
@@ -1,16 +1,16 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Serialization;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Serialization;
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
{
@@ -136,6 +136,39 @@ namespace MediaBrowser.Api
public class UserService : BaseRestService
{
/// <summary>
+ /// The _XML serializer
+ /// </summary>
+ private readonly IXmlSerializer _xmlSerializer;
+
+ /// <summary>
+ /// The _json serializer
+ /// </summary>
+ private readonly IJsonSerializer _jsonSerializer;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="UserService" /> class.
+ /// </summary>
+ /// <param name="xmlSerializer">The XML serializer.</param>
+ /// <param name="jsonSerializer">The json serializer.</param>
+ /// <exception cref="System.ArgumentNullException">xmlSerializer</exception>
+ public UserService(IXmlSerializer xmlSerializer, IJsonSerializer jsonSerializer)
+ : base()
+ {
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
+
+ if (xmlSerializer == null)
+ {
+ throw new ArgumentNullException("xmlSerializer");
+ }
+
+ _jsonSerializer = jsonSerializer;
+ _xmlSerializer = xmlSerializer;
+ }
+
+ /// <summary>
/// Gets the specified request.
/// </summary>
/// <param name="request">The request.</param>
@@ -262,10 +295,10 @@ namespace MediaBrowser.Api
// https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs
var pathInfo = PathInfo.Parse(Request.PathInfo);
var id = new Guid(pathInfo.GetArgumentValue<string>(1));
-
+
var kernel = (Kernel)Kernel;
- var dtoUser = JsonSerializer.DeserializeFromStream<UserDto>(request.RequestStream);
+ var dtoUser = _jsonSerializer.DeserializeFromStream<UserDto>(request.RequestStream);
var user = kernel.GetUserById(id);
@@ -273,7 +306,7 @@ namespace MediaBrowser.Api
Task.WaitAll(task);
- user.UpdateConfiguration(dtoUser.Configuration);
+ user.UpdateConfiguration(dtoUser.Configuration, _xmlSerializer);
}
/// <summary>
@@ -285,7 +318,7 @@ namespace MediaBrowser.Api
{
var kernel = (Kernel)Kernel;
- var dtoUser = JsonSerializer.DeserializeFromStream<UserDto>(request.RequestStream);
+ var dtoUser = _jsonSerializer.DeserializeFromStream<UserDto>(request.RequestStream);
var newUser = kernel.UserManager.CreateUser(dtoUser.Name).Result;
diff --git a/MediaBrowser.ApiInteraction.Javascript/MediaBrowser.ApiInteraction.Javascript.csproj b/MediaBrowser.ApiInteraction.Javascript/MediaBrowser.ApiInteraction.Javascript.csproj
deleted file mode 100644
index 68e8c880d..000000000
--- a/MediaBrowser.ApiInteraction.Javascript/MediaBrowser.ApiInteraction.Javascript.csproj
+++ /dev/null
@@ -1,105 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{767B536E-D90C-4D74-A14B-8564B16F3499}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>MediaBrowser.ApiInteraction.Javascript</RootNamespace>
- <AssemblyName>MediaBrowser.ApiInteraction.Javascript</AssemblyName>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
- <RestorePackages>true</RestorePackages>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup>
- <RunPostBuildEvent>Always</RunPostBuildEvent>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="ServiceStack, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\ServiceStack.3.9.37\lib\net35\ServiceStack.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.Common, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Common.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.Interfaces, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Interfaces.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.OrmLite, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\ServiceStack.OrmLite.SqlServer.3.9.37\lib\ServiceStack.OrmLite.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.OrmLite.SqlServer, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\ServiceStack.OrmLite.SqlServer.3.9.37\lib\ServiceStack.OrmLite.SqlServer.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.Redis, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\ServiceStack.Redis.3.9.37\lib\net35\ServiceStack.Redis.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.ServiceInterface, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\ServiceStack.3.9.37\lib\net35\ServiceStack.ServiceInterface.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.Text, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\ServiceStack.Text.3.9.37\lib\net35\ServiceStack.Text.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="Microsoft.CSharp" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="..\SharedVersion.cs">
- <Link>Properties\SharedVersion.cs</Link>
- </Compile>
- <Compile Include="JavascriptApiClientService.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
- <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
- <Name>MediaBrowser.Common</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="ApiClient.js" />
- </ItemGroup>
- <ItemGroup>
- <None Include="packages.config" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <PropertyGroup>
- <PostBuildEvent>xcopy "$(TargetPath)" "$(SolutionDir)\MediaBrowser.ServerApplication\CorePlugins\" /y</PostBuildEvent>
- </PropertyGroup>
- <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/MediaBrowser.ApiInteraction.Javascript/Properties/AssemblyInfo.cs b/MediaBrowser.ApiInteraction.Javascript/Properties/AssemblyInfo.cs
deleted file mode 100644
index 1a0333e49..000000000
--- a/MediaBrowser.ApiInteraction.Javascript/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("MediaBrowser.ApiInteraction.Javascript")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("MediaBrowser.ApiInteraction.Javascript")]
-[assembly: AssemblyCopyright("Copyright © 2012")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("97f9d4da-d7de-47d9-ae68-06d78679d327")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-// \ No newline at end of file
diff --git a/MediaBrowser.ApiInteraction.Javascript/packages.config b/MediaBrowser.ApiInteraction.Javascript/packages.config
deleted file mode 100644
index ea25110aa..000000000
--- a/MediaBrowser.ApiInteraction.Javascript/packages.config
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="ServiceStack" version="3.9.37" targetFramework="net45" />
- <package id="ServiceStack.Common" version="3.9.37" targetFramework="net45" />
- <package id="ServiceStack.OrmLite.SqlServer" version="3.9.37" targetFramework="net45" />
- <package id="ServiceStack.Redis" version="3.9.37" targetFramework="net45" />
- <package id="ServiceStack.Text" version="3.9.37" targetFramework="net45" />
-</packages> \ No newline at end of file
diff --git a/MediaBrowser.Common/Kernel/BaseApplicationPaths.cs b/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs
index 936c484c8..93478b22c 100644
--- a/MediaBrowser.Common/Kernel/BaseApplicationPaths.cs
+++ b/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs
@@ -3,7 +3,7 @@ using System.Configuration;
using System.IO;
using System.Reflection;
-namespace MediaBrowser.Common.Kernel
+namespace MediaBrowser.Common.Implementations
{
/// <summary>
/// Provides a base class to hold common application paths used by both the Ui and Server.
diff --git a/MediaBrowser.Server.WorldWeatherOnline/MediaBrowser.Server.WorldWeatherOnline.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
index 1e97a482e..d271db060 100644
--- a/MediaBrowser.Server.WorldWeatherOnline/MediaBrowser.Server.WorldWeatherOnline.csproj
+++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
@@ -4,13 +4,15 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{973CA45C-8362-490B-8327-C68098FD4891}</ProjectGuid>
+ <ProjectGuid>{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>MediaBrowser.Server.WorldWeatherOnline</RootNamespace>
- <AssemblyName>MediaBrowser.Server.WorldWeatherOnline</AssemblyName>
+ <RootNamespace>MediaBrowser.Common.Implementations</RootNamespace>
+ <AssemblyName>MediaBrowser.Common.Implementations</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -29,39 +31,52 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
- <PropertyGroup>
- <RunPostBuildEvent>Always</RunPostBuildEvent>
- </PropertyGroup>
<ItemGroup>
+ <Reference Include="protobuf-net">
+ <HintPath>..\packages\protobuf-net.2.0.0.621\lib\net40\protobuf-net.dll</HintPath>
+ </Reference>
+ <Reference Include="ServiceStack.Text">
+ <HintPath>..\packages\ServiceStack.Text.3.9.37\lib\net35\ServiceStack.Text.dll</HintPath>
+ </Reference>
<Reference Include="System" />
+ <Reference Include="System.Configuration" />
<Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link>
</Compile>
+ <Compile Include="BaseApplicationPaths.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="WeatherProvider.cs" />
+ <Compile Include="ScheduledTasks\TaskManager.cs" />
+ <Compile Include="ScheduledTasks\Tasks\DeleteCacheFileTask.cs" />
+ <Compile Include="ScheduledTasks\Tasks\DeleteLogFileTask.cs" />
+ <Compile Include="ScheduledTasks\Tasks\ReloadLoggerTask.cs" />
+ <Compile Include="ScheduledTasks\Tasks\SystemUpdateTask.cs" />
+ <Compile Include="Serialization\JsonSerializer.cs" />
+ <Compile Include="Serialization\ProtobufSerializer.cs" />
+ <Compile Include="Serialization\XmlSerializer.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
<Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
<Name>MediaBrowser.Common</Name>
</ProjectReference>
- <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj">
- <Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
- <Name>MediaBrowser.Controller</Name>
- </ProjectReference>
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
<Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
<Name>MediaBrowser.Model</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <PropertyGroup>
- <PostBuildEvent>xcopy "$(TargetPath)" "$(SolutionDir)\MediaBrowser.ServerApplication\CorePlugins\" /y</PostBuildEvent>
- </PropertyGroup>
+ <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
diff --git a/MediaBrowser.Server.Sqlite/Properties/AssemblyInfo.cs b/MediaBrowser.Common.Implementations/Properties/AssemblyInfo.cs
index 7c69b5544..f9c3e0bd1 100644
--- a/MediaBrowser.Server.Sqlite/Properties/AssemblyInfo.cs
+++ b/MediaBrowser.Common.Implementations/Properties/AssemblyInfo.cs
@@ -5,11 +5,11 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-[assembly: AssemblyTitle("MediaBrowser.Server.Sqlite")]
+[assembly: AssemblyTitle("MediaBrowser.Common.Implementations")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("MediaBrowser.Server.Sqlite")]
+[assembly: AssemblyProduct("MediaBrowser.Common.Implementations")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -20,7 +20,7 @@ using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("f46c9f4b-24ed-49e1-be19-4b6242dd8382")]
+[assembly: Guid("fc7d85c6-0fe7-4db6-8158-54f7b18f17cd")]
// Version information for an assembly consists of the following four values:
//
@@ -28,4 +28,4 @@ using System.Runtime.InteropServices;
// Minor Version
// Build Number
// Revision
-// \ No newline at end of file
+//
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs
new file mode 100644
index 000000000..c6eca29d1
--- /dev/null
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs
@@ -0,0 +1,322 @@
+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;
+using System.IO;
+using System.Linq;
+
+namespace MediaBrowser.Common.Implementations.ScheduledTasks
+{
+ /// <summary>
+ /// Class TaskManager
+ /// </summary>
+ public class TaskManager : ITaskManager
+ {
+ /// <summary>
+ /// Gets the list of Scheduled Tasks
+ /// </summary>
+ /// <value>The scheduled tasks.</value>
+ public IScheduledTask[] ScheduledTasks { get; private set; }
+
+ /// <summary>
+ /// The _task queue
+ /// </summary>
+ private readonly List<Type> _taskQueue = new List<Type>();
+
+ /// <summary>
+ /// The _logger
+ /// </summary>
+ private readonly ILogger _logger;
+
+ /// <summary>
+ /// The _application paths
+ /// </summary>
+ private readonly IApplicationPaths _applicationPaths;
+
+ /// <summary>
+ /// The _json serializer
+ /// </summary>
+ private readonly IJsonSerializer _jsonSerializer;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TaskManager" /> class.
+ /// </summary>
+ /// <param name="applicationPaths">The application paths.</param>
+ /// <param name="jsonSerializer">The json serializer.</param>
+ /// <param name="logger">The logger.</param>
+ /// <exception cref="System.ArgumentException">kernel</exception>
+ public TaskManager(IApplicationPaths applicationPaths, IJsonSerializer jsonSerializer, ILogger logger)
+ {
+ if (applicationPaths == null)
+ {
+ throw new ArgumentException("applicationPaths");
+ }
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentException("jsonSerializer");
+ }
+ if (logger == null)
+ {
+ throw new ArgumentException("logger");
+ }
+
+ _applicationPaths = applicationPaths;
+ _jsonSerializer = jsonSerializer;
+ _logger = logger;
+
+ ScheduledTasks = new IScheduledTask[] {};
+ }
+
+ /// <summary>
+ /// Cancels if running and queue.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ public void CancelIfRunningAndQueue<T>()
+ where T : IScheduledTask
+ {
+ ScheduledTasks.OfType<T>().First().CancelIfRunning();
+ QueueScheduledTask<T>();
+ }
+
+ /// <summary>
+ /// Queues the scheduled task.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ public void QueueScheduledTask<T>()
+ where T : IScheduledTask
+ {
+ var scheduledTask = ScheduledTasks.OfType<T>().First();
+
+ QueueScheduledTask(scheduledTask);
+ }
+
+ /// <summary>
+ /// Queues the scheduled task.
+ /// </summary>
+ /// <param name="task">The task.</param>
+ public void QueueScheduledTask(IScheduledTask task)
+ {
+ var type = task.GetType();
+
+ var scheduledTask = ScheduledTasks.First(t => t.GetType() == type);
+
+ lock (_taskQueue)
+ {
+ // If it's idle just execute immediately
+ if (scheduledTask.State == TaskState.Idle)
+ {
+ scheduledTask.Execute();
+ return;
+ }
+
+ if (!_taskQueue.Contains(type))
+ {
+ _logger.Info("Queueing task {0}", type.Name);
+ _taskQueue.Add(type);
+ }
+ else
+ {
+ _logger.Info("Task already queued: {0}", type.Name);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Called when [task completed].
+ /// </summary>
+ /// <param name="task">The task.</param>
+ public void OnTaskCompleted(IScheduledTask task)
+ {
+ // Execute queued tasks
+ lock (_taskQueue)
+ {
+ var copy = _taskQueue.ToList();
+
+ foreach (var type in copy)
+ {
+ var scheduledTask = ScheduledTasks.First(t => t.GetType() == type);
+
+ if (scheduledTask.State == TaskState.Idle)
+ {
+ scheduledTask.Execute();
+
+ _taskQueue.Remove(type);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds the tasks.
+ /// </summary>
+ /// <param name="tasks">The tasks.</param>
+ public void AddTasks(IEnumerable<IScheduledTask> tasks)
+ {
+ var myTasks = ScheduledTasks.ToList();
+
+ myTasks.AddRange(tasks);
+
+ ScheduledTasks = myTasks.ToArray();
+ }
+
+ /// <summary>
+ /// The _scheduled tasks configuration directory
+ /// </summary>
+ private string _scheduledTasksConfigurationDirectory;
+ /// <summary>
+ /// Gets the scheduled tasks configuration directory.
+ /// </summary>
+ /// <value>The scheduled tasks configuration directory.</value>
+ private string ScheduledTasksConfigurationDirectory
+ {
+ get
+ {
+ if (_scheduledTasksConfigurationDirectory == null)
+ {
+ _scheduledTasksConfigurationDirectory = Path.Combine(_applicationPaths.ConfigurationDirectoryPath, "ScheduledTasks");
+
+ if (!Directory.Exists(_scheduledTasksConfigurationDirectory))
+ {
+ Directory.CreateDirectory(_scheduledTasksConfigurationDirectory);
+ }
+ }
+ return _scheduledTasksConfigurationDirectory;
+ }
+ }
+
+ /// <summary>
+ /// The _scheduled tasks data directory
+ /// </summary>
+ private string _scheduledTasksDataDirectory;
+ /// <summary>
+ /// Gets the scheduled tasks data directory.
+ /// </summary>
+ /// <value>The scheduled tasks data directory.</value>
+ private string ScheduledTasksDataDirectory
+ {
+ get
+ {
+ if (_scheduledTasksDataDirectory == null)
+ {
+ _scheduledTasksDataDirectory = Path.Combine(_applicationPaths.DataPath, "ScheduledTasks");
+
+ if (!Directory.Exists(_scheduledTasksDataDirectory))
+ {
+ Directory.CreateDirectory(_scheduledTasksDataDirectory);
+ }
+ }
+ return _scheduledTasksDataDirectory;
+ }
+ }
+
+ /// <summary>
+ /// Gets the history file path.
+ /// </summary>
+ /// <value>The history file path.</value>
+ private string GetHistoryFilePath(IScheduledTask task)
+ {
+ return Path.Combine(ScheduledTasksDataDirectory, task.Id + ".js");
+ }
+
+ /// <summary>
+ /// Gets the configuration file path.
+ /// </summary>
+ /// <param name="task">The task.</param>
+ /// <returns>System.String.</returns>
+ private string GetConfigurationFilePath(IScheduledTask task)
+ {
+ return Path.Combine(ScheduledTasksConfigurationDirectory, task.Id + ".js");
+ }
+
+ /// <summary>
+ /// Called when [task completed].
+ /// </summary>
+ /// <param name="task">The task.</param>
+ /// <param name="startTime">The start time.</param>
+ /// <param name="endTime">The end time.</param>
+ /// <param name="status">The status.</param>
+ public void OnTaskCompleted(IScheduledTask task, DateTime startTime, DateTime endTime, TaskCompletionStatus status)
+ {
+ var elapsedTime = endTime - startTime;
+
+ _logger.Info("{0} {1} after {2} minute(s) and {3} seconds", task.Name, status, Math.Truncate(elapsedTime.TotalMinutes), elapsedTime.Seconds);
+
+ var result = new TaskResult
+ {
+ StartTimeUtc = startTime,
+ EndTimeUtc = endTime,
+ Status = status,
+ Name = task.Name,
+ Id = task.Id
+ };
+
+ _jsonSerializer.SerializeToFile(result, GetHistoryFilePath(task));
+
+ //task.LastExecutionResult = result;
+ }
+
+ /// <summary>
+ /// Gets the last execution result.
+ /// </summary>
+ /// <param name="task">The task.</param>
+ /// <returns>TaskResult.</returns>
+ public TaskResult GetLastExecutionResult(IScheduledTask task)
+ {
+ return _jsonSerializer.DeserializeFromFile<TaskResult>(GetHistoryFilePath(task));
+ }
+
+ /// <summary>
+ /// Loads the triggers.
+ /// </summary>
+ /// <param name="task">The task.</param>
+ /// <returns>IEnumerable{BaseTaskTrigger}.</returns>
+ public IEnumerable<ITaskTrigger> LoadTriggers(IScheduledTask task)
+ {
+ try
+ {
+ return _jsonSerializer.DeserializeFromFile<IEnumerable<TaskTriggerInfo>>(GetConfigurationFilePath(task))
+ .Select(ScheduledTaskHelpers.GetTrigger)
+ .ToList();
+ }
+ catch (IOException)
+ {
+ // File doesn't exist. No biggie. Return defaults.
+ return task.GetDefaultTriggers();
+ }
+ }
+
+ /// <summary>
+ /// Saves the triggers.
+ /// </summary>
+ /// <param name="task">The task.</param>
+ /// <param name="triggers">The triggers.</param>
+ public void SaveTriggers(IScheduledTask task, IEnumerable<ITaskTrigger> triggers)
+ {
+ _jsonSerializer.SerializeToFile(triggers.Select(ScheduledTaskHelpers.GetTriggerInfo), GetConfigurationFilePath(task));
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources.
+ /// </summary>
+ /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+ protected virtual void Dispose(bool dispose)
+ {
+ foreach (var task in ScheduledTasks)
+ {
+ task.Dispose();
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Common/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
index b06134ee2..2ef056658 100644
--- a/MediaBrowser.Common/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Common.Kernel;
+using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Generic;
@@ -7,7 +8,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-namespace MediaBrowser.Common.ScheduledTasks.Tasks
+namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
{
/// <summary>
/// Deletes old cache files
@@ -29,7 +30,7 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
/// Creates the triggers that define when the task will run
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- protected override IEnumerable<BaseTaskTrigger> GetDefaultTriggers()
+ public override IEnumerable<ITaskTrigger> GetDefaultTriggers()
{
var trigger = new DailyTrigger { TimeOfDay = TimeSpan.FromHours(2) }; //2am
diff --git a/MediaBrowser.Common/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
index 0b243cb10..dd00a7148 100644
--- a/MediaBrowser.Common/ScheduledTasks/Tasks/DeleteLogFileTask.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Common.Kernel;
+using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Generic;
@@ -7,7 +8,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-namespace MediaBrowser.Common.ScheduledTasks.Tasks
+namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
{
/// <summary>
/// Deletes old log files
@@ -29,7 +30,7 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
/// Creates the triggers that define when the task will run
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- protected override IEnumerable<BaseTaskTrigger> GetDefaultTriggers()
+ public override IEnumerable<ITaskTrigger> GetDefaultTriggers()
{
var trigger = new DailyTrigger { TimeOfDay = TimeSpan.FromHours(2) }; //2am
diff --git a/MediaBrowser.Common/ScheduledTasks/Tasks/ReloadLoggerTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs
index 35cbe98f1..79c633c76 100644
--- a/MediaBrowser.Common/ScheduledTasks/Tasks/ReloadLoggerTask.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs
@@ -1,11 +1,12 @@
using MediaBrowser.Common.Kernel;
+using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
-namespace MediaBrowser.Common.ScheduledTasks.Tasks
+namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
{
/// <summary>
/// Class ReloadLoggerFileTask
@@ -27,7 +28,7 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
/// Gets the default triggers.
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- protected override IEnumerable<BaseTaskTrigger> GetDefaultTriggers()
+ public override IEnumerable<ITaskTrigger> GetDefaultTriggers()
{
var trigger = new DailyTrigger { TimeOfDay = TimeSpan.FromHours(0) }; //12am
diff --git a/MediaBrowser.Common/ScheduledTasks/Tasks/SystemUpdateTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs
index f02293a5e..a101ad3dd 100644
--- a/MediaBrowser.Common/ScheduledTasks/Tasks/SystemUpdateTask.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs
@@ -1,11 +1,12 @@
using MediaBrowser.Common.Kernel;
+using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
-namespace MediaBrowser.Common.ScheduledTasks.Tasks
+namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
{
/// <summary>
/// Plugin Update Task
@@ -34,9 +35,9 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
/// Creates the triggers that define when the task will run
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- protected override IEnumerable<BaseTaskTrigger> GetDefaultTriggers()
+ public override IEnumerable<ITaskTrigger> GetDefaultTriggers()
{
- return new BaseTaskTrigger[] {
+ return new ITaskTrigger[] {
// 1am
new DailyTrigger { TimeOfDay = TimeSpan.FromHours(1) },
diff --git a/MediaBrowser.Common/Serialization/JsonSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs
index 5b6e354a8..bc8935a86 100644
--- a/MediaBrowser.Common/Serialization/JsonSerializer.cs
+++ b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs
@@ -1,13 +1,19 @@
-using System;
+using MediaBrowser.Model.Serialization;
+using System;
using System.IO;
-namespace MediaBrowser.Common.Serialization
+namespace MediaBrowser.Common.Implementations.Serialization
{
/// <summary>
/// Provides a wrapper around third party json serialization.
/// </summary>
- public class JsonSerializer
+ public class JsonSerializer : IJsonSerializer
{
+ public JsonSerializer()
+ {
+ Configure();
+ }
+
/// <summary>
/// Serializes to stream.
/// </summary>
@@ -15,7 +21,7 @@ namespace MediaBrowser.Common.Serialization
/// <param name="obj">The obj.</param>
/// <param name="stream">The stream.</param>
/// <exception cref="System.ArgumentNullException">obj</exception>
- public static void SerializeToStream<T>(T obj, Stream stream)
+ public void SerializeToStream<T>(T obj, Stream stream)
where T : class
{
if (obj == null)
@@ -28,8 +34,6 @@ namespace MediaBrowser.Common.Serialization
throw new ArgumentNullException("stream");
}
- Configure();
-
ServiceStack.Text.JsonSerializer.SerializeToStream(obj, obj.GetType(), stream);
}
@@ -40,7 +44,7 @@ namespace MediaBrowser.Common.Serialization
/// <param name="obj">The obj.</param>
/// <param name="file">The file.</param>
/// <exception cref="System.ArgumentNullException">obj</exception>
- public static void SerializeToFile<T>(T obj, string file)
+ public void SerializeToFile<T>(T obj, string file)
where T : class
{
if (obj == null)
@@ -53,8 +57,6 @@ namespace MediaBrowser.Common.Serialization
throw new ArgumentNullException("file");
}
- Configure();
-
using (Stream stream = File.Open(file, FileMode.Create))
{
SerializeToStream(obj, stream);
@@ -68,7 +70,7 @@ namespace MediaBrowser.Common.Serialization
/// <param name="file">The file.</param>
/// <returns>System.Object.</returns>
/// <exception cref="System.ArgumentNullException">type</exception>
- public static object DeserializeFromFile(Type type, string file)
+ public object DeserializeFromFile(Type type, string file)
{
if (type == null)
{
@@ -80,8 +82,6 @@ namespace MediaBrowser.Common.Serialization
throw new ArgumentNullException("file");
}
- Configure();
-
using (Stream stream = File.OpenRead(file))
{
return ServiceStack.Text.JsonSerializer.DeserializeFromStream(type, stream);
@@ -95,7 +95,7 @@ namespace MediaBrowser.Common.Serialization
/// <param name="file">The file.</param>
/// <returns>``0.</returns>
/// <exception cref="System.ArgumentNullException">file</exception>
- public static T DeserializeFromFile<T>(string file)
+ public T DeserializeFromFile<T>(string file)
where T : class
{
if (string.IsNullOrEmpty(file))
@@ -103,8 +103,6 @@ namespace MediaBrowser.Common.Serialization
throw new ArgumentNullException("file");
}
- Configure();
-
using (Stream stream = File.OpenRead(file))
{
return ServiceStack.Text.JsonSerializer.DeserializeFromStream<T>(stream);
@@ -118,15 +116,13 @@ namespace MediaBrowser.Common.Serialization
/// <param name="stream">The stream.</param>
/// <returns>``0.</returns>
/// <exception cref="System.ArgumentNullException">stream</exception>
- public static T DeserializeFromStream<T>(Stream stream)
+ public T DeserializeFromStream<T>(Stream stream)
{
if (stream == null)
{
throw new ArgumentNullException("stream");
}
- Configure();
-
return ServiceStack.Text.JsonSerializer.DeserializeFromStream<T>(stream);
}
@@ -137,15 +133,13 @@ namespace MediaBrowser.Common.Serialization
/// <param name="text">The text.</param>
/// <returns>``0.</returns>
/// <exception cref="System.ArgumentNullException">text</exception>
- public static T DeserializeFromString<T>(string text)
+ public T DeserializeFromString<T>(string text)
{
if (string.IsNullOrEmpty(text))
{
throw new ArgumentNullException("text");
}
- Configure();
-
return ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(text);
}
@@ -156,7 +150,7 @@ namespace MediaBrowser.Common.Serialization
/// <param name="type">The type.</param>
/// <returns>System.Object.</returns>
/// <exception cref="System.ArgumentNullException">stream</exception>
- public static object DeserializeFromStream(Stream stream, Type type)
+ public object DeserializeFromStream(Stream stream, Type type)
{
if (stream == null)
{
@@ -168,27 +162,17 @@ namespace MediaBrowser.Common.Serialization
throw new ArgumentNullException("type");
}
- Configure();
-
return ServiceStack.Text.JsonSerializer.DeserializeFromStream(type, stream);
}
/// <summary>
- /// The _is configured
- /// </summary>
- private static bool _isConfigured;
- /// <summary>
/// Configures this instance.
/// </summary>
- internal static void Configure()
+ private void Configure()
{
- if (!_isConfigured)
- {
- ServiceStack.Text.JsConfig.DateHandler = ServiceStack.Text.JsonDateHandler.ISO8601;
- ServiceStack.Text.JsConfig.ExcludeTypeInfo = true;
- ServiceStack.Text.JsConfig.IncludeNullValues = false;
- _isConfigured = true;
- }
+ ServiceStack.Text.JsConfig.DateHandler = ServiceStack.Text.JsonDateHandler.ISO8601;
+ ServiceStack.Text.JsConfig.ExcludeTypeInfo = true;
+ ServiceStack.Text.JsConfig.IncludeNullValues = false;
}
/// <summary>
@@ -198,7 +182,7 @@ namespace MediaBrowser.Common.Serialization
/// <param name="type">The type.</param>
/// <returns>System.Object.</returns>
/// <exception cref="System.ArgumentNullException">json</exception>
- public static object DeserializeFromString(string json, Type type)
+ public object DeserializeFromString(string json, Type type)
{
if (string.IsNullOrEmpty(json))
{
@@ -210,8 +194,6 @@ namespace MediaBrowser.Common.Serialization
throw new ArgumentNullException("type");
}
- Configure();
-
return ServiceStack.Text.JsonSerializer.DeserializeFromString(json, type);
}
@@ -222,7 +204,7 @@ namespace MediaBrowser.Common.Serialization
/// <param name="obj">The obj.</param>
/// <returns>System.String.</returns>
/// <exception cref="System.ArgumentNullException">obj</exception>
- public static string SerializeToString<T>(T obj)
+ public string SerializeToString<T>(T obj)
where T : class
{
if (obj == null)
@@ -230,7 +212,6 @@ namespace MediaBrowser.Common.Serialization
throw new ArgumentNullException("obj");
}
- Configure();
return ServiceStack.Text.JsonSerializer.SerializeToString(obj, obj.GetType());
}
@@ -241,7 +222,7 @@ namespace MediaBrowser.Common.Serialization
/// <param name="obj">The obj.</param>
/// <returns>System.Byte[][].</returns>
/// <exception cref="System.ArgumentNullException">obj</exception>
- public static byte[] SerializeToBytes<T>(T obj)
+ public byte[] SerializeToBytes<T>(T obj)
where T : class
{
if (obj == null)
diff --git a/MediaBrowser.Common/Serialization/DynamicProtobufSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/ProtobufSerializer.cs
index 359cf9da0..85325f3c1 100644
--- a/MediaBrowser.Common/Serialization/DynamicProtobufSerializer.cs
+++ b/MediaBrowser.Common.Implementations/Serialization/ProtobufSerializer.cs
@@ -1,22 +1,23 @@
-using ProtoBuf;
+using MediaBrowser.Model.Serialization;
+using ProtoBuf;
using ProtoBuf.Meta;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-namespace MediaBrowser.Common.Serialization
+namespace MediaBrowser.Common.Implementations.Serialization
{
/// <summary>
/// Creates a compiled protobuf serializer based on a set of assemblies
/// </summary>
- public class DynamicProtobufSerializer
+ public class ProtobufSerializer : IProtobufSerializer
{
/// <summary>
/// Gets or sets the type model.
/// </summary>
/// <value>The type model.</value>
- public TypeModel TypeModel { get; set; }
+ private TypeModel TypeModel { get; set; }
/// <summary>
/// Serializes to stream.
@@ -135,7 +136,7 @@ namespace MediaBrowser.Common.Serialization
/// </summary>
/// <returns>DynamicProtobufSerializer.</returns>
/// <exception cref="System.ArgumentNullException">assemblies</exception>
- public static DynamicProtobufSerializer Create(IEnumerable<Type> types)
+ public static ProtobufSerializer Create(IEnumerable<Type> types)
{
if (types == null)
{
@@ -151,7 +152,7 @@ namespace MediaBrowser.Common.Serialization
model.Add(type, true);
}
- return new DynamicProtobufSerializer { TypeModel = model.Compile() };
+ return new ProtobufSerializer { TypeModel = model.Compile() };
}
}
}
diff --git a/MediaBrowser.Common/Serialization/XmlSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs
index 07010a5d2..d01199f6f 100644
--- a/MediaBrowser.Common/Serialization/XmlSerializer.cs
+++ b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs
@@ -1,35 +1,21 @@
-using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
using System;
using System.IO;
-using System.Linq;
using System.Xml;
-namespace MediaBrowser.Common.Serialization
+namespace MediaBrowser.Common.Implementations.Serialization
{
/// <summary>
/// Provides a wrapper around third party xml serialization.
/// </summary>
- public class XmlSerializer
+ public class XmlSerializer : IXmlSerializer
{
/// <summary>
/// Serializes to writer.
/// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="obj">The obj.</param>
- /// <param name="writer">The writer.</param>
- public static void SerializeToWriter<T>(T obj, XmlTextWriter writer)
- {
- writer.Formatting = Formatting.Indented;
- var netSerializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
- netSerializer.Serialize(writer, obj);
- }
-
- /// <summary>
- /// Serializes to writer.
- /// </summary>
/// <param name="obj">The obj.</param>
/// <param name="writer">The writer.</param>
- public static void SerializeToWriter(object obj, XmlTextWriter writer)
+ private void SerializeToWriter(object obj, XmlTextWriter writer)
{
writer.Formatting = Formatting.Indented;
var netSerializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
@@ -42,7 +28,7 @@ namespace MediaBrowser.Common.Serialization
/// <typeparam name="T"></typeparam>
/// <param name="stream">The stream.</param>
/// <returns>``0.</returns>
- public static T DeserializeFromStream<T>(Stream stream)
+ public T DeserializeFromStream<T>(Stream stream)
{
using (var reader = new XmlTextReader(stream))
{
@@ -58,7 +44,7 @@ namespace MediaBrowser.Common.Serialization
/// <param name="type">The type.</param>
/// <param name="stream">The stream.</param>
/// <returns>System.Object.</returns>
- public static object DeserializeFromStream(Type type, Stream stream)
+ public object DeserializeFromStream(Type type, Stream stream)
{
using (var reader = new XmlTextReader(stream))
{
@@ -73,7 +59,7 @@ namespace MediaBrowser.Common.Serialization
/// </summary>
/// <param name="obj">The obj.</param>
/// <param name="stream">The stream.</param>
- public static void SerializeToStream(object obj, Stream stream)
+ public void SerializeToStream(object obj, Stream stream)
{
using (var writer = new XmlTextWriter(stream, null))
{
@@ -87,7 +73,7 @@ namespace MediaBrowser.Common.Serialization
/// <typeparam name="T"></typeparam>
/// <param name="file">The file.</param>
/// <returns>``0.</returns>
- public static T DeserializeFromFile<T>(string file)
+ public T DeserializeFromFile<T>(string file)
{
using (var stream = File.OpenRead(file))
{
@@ -100,7 +86,7 @@ namespace MediaBrowser.Common.Serialization
/// </summary>
/// <param name="obj">The obj.</param>
/// <param name="file">The file.</param>
- public static void SerializeToFile(object obj, string file)
+ public void SerializeToFile(object obj, string file)
{
using (var stream = new FileStream(file, FileMode.Create))
{
@@ -114,7 +100,7 @@ namespace MediaBrowser.Common.Serialization
/// <param name="type">The type.</param>
/// <param name="file">The file.</param>
/// <returns>System.Object.</returns>
- public static object DeserializeFromFile(Type type, string file)
+ public object DeserializeFromFile(Type type, string file)
{
using (var stream = File.OpenRead(file))
{
@@ -128,7 +114,7 @@ namespace MediaBrowser.Common.Serialization
/// <param name="type">The type.</param>
/// <param name="buffer">The buffer.</param>
/// <returns>System.Object.</returns>
- public static object DeserializeFromBytes(Type type, byte[] buffer)
+ public object DeserializeFromBytes(Type type, byte[] buffer)
{
using (var stream = new MemoryStream(buffer))
{
@@ -141,7 +127,7 @@ namespace MediaBrowser.Common.Serialization
/// </summary>
/// <param name="obj">The obj.</param>
/// <returns>System.Byte[][].</returns>
- public static byte[] SerializeToBytes(object obj)
+ public byte[] SerializeToBytes(object obj)
{
using (var stream = new MemoryStream())
{
@@ -150,63 +136,5 @@ namespace MediaBrowser.Common.Serialization
return stream.ToArray();
}
}
-
- /// <summary>
- /// Reads an xml configuration file from the file system
- /// It will immediately re-serialize and save if new serialization data is available due to property changes
- /// </summary>
- /// <param name="type">The type.</param>
- /// <param name="path">The path.</param>
- /// <param name="logger">The logger.</param>
- /// <returns>System.Object.</returns>
- public static object GetXmlConfiguration(Type type, string path, ILogger logger)
- {
- logger.Info("Loading {0} at {1}", type.Name, path);
-
- object configuration;
-
- byte[] buffer = null;
-
- // Use try/catch to avoid the extra file system lookup using File.Exists
- try
- {
- buffer = File.ReadAllBytes(path);
-
- configuration = DeserializeFromBytes(type, buffer);
- }
- catch (FileNotFoundException)
- {
- configuration = Activator.CreateInstance(type);
- }
-
- // Take the object we just got and serialize it back to bytes
- var newBytes = SerializeToBytes(configuration);
-
- // If the file didn't exist before, or if something has changed, re-save
- if (buffer == null || !buffer.SequenceEqual(newBytes))
- {
- logger.Info("Saving {0} to {1}", type.Name, path);
-
- // Save it after load in case we got new items
- File.WriteAllBytes(path, newBytes);
- }
-
- return configuration;
- }
-
- /// <summary>
- /// Reads an xml configuration file from the file system
- /// It will immediately save the configuration after loading it, just
- /// in case there are new serializable properties
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="path">The path.</param>
- /// <param name="logger">The logger.</param>
- /// <returns>``0.</returns>
- public static T GetXmlConfiguration<T>(string path, ILogger logger)
- where T : class
- {
- return GetXmlConfiguration(typeof(T), path, logger) as T;
- }
}
}
diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config
new file mode 100644
index 000000000..14eb42cac
--- /dev/null
+++ b/MediaBrowser.Common.Implementations/packages.config
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="protobuf-net" version="2.0.0.621" targetFramework="net45" />
+ <package id="ServiceStack.Text" version="3.9.37" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/MediaBrowser.Common/Kernel/BaseKernel.cs b/MediaBrowser.Common/Kernel/BaseKernel.cs
index 28ccd8602..a5a9b46ec 100644
--- a/MediaBrowser.Common/Kernel/BaseKernel.cs
+++ b/MediaBrowser.Common/Kernel/BaseKernel.cs
@@ -2,16 +2,14 @@
using MediaBrowser.Common.Net;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.ScheduledTasks;
-using MediaBrowser.Common.Serialization;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.System;
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.IO;
using System.Linq;
-using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
@@ -24,7 +22,7 @@ namespace MediaBrowser.Common.Kernel
/// <typeparam name="TApplicationPathsType">The type of the T application paths type.</typeparam>
public abstract class BaseKernel<TConfigurationType, TApplicationPathsType> : IDisposable, IKernel
where TConfigurationType : BaseApplicationConfiguration, new()
- where TApplicationPathsType : BaseApplicationPaths, new()
+ where TApplicationPathsType : IApplicationPaths
{
/// <summary>
/// Occurs when [has pending restart changed].
@@ -129,7 +127,7 @@ namespace MediaBrowser.Common.Kernel
get
{
// Lazy load
- LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationLoaded, ref _configurationSyncLock, () => XmlSerializer.GetXmlConfiguration<TConfigurationType>(ApplicationPaths.SystemConfigurationFilePath, Logger));
+ LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationLoaded, ref _configurationSyncLock, () => GetXmlConfiguration<TConfigurationType>(ApplicationPaths.SystemConfigurationFilePath));
return _configuration;
}
protected set
@@ -162,19 +160,6 @@ namespace MediaBrowser.Common.Kernel
public TApplicationPathsType ApplicationPaths { get; private set; }
/// <summary>
- /// The _failed assembly loads
- /// </summary>
- private readonly List<string> _failedPluginAssemblies = new List<string>();
- /// <summary>
- /// Gets the plugin assemblies that failed to load.
- /// </summary>
- /// <value>The failed assembly loads.</value>
- public IEnumerable<string> FailedPluginAssemblies
- {
- get { return _failedPluginAssemblies; }
- }
-
- /// <summary>
/// Gets the list of currently loaded plugins
/// </summary>
/// <value>The plugins.</value>
@@ -205,46 +190,6 @@ namespace MediaBrowser.Common.Kernel
public IEnumerable<IRestfulService> RestServices { get; private set; }
/// <summary>
- /// The disposable parts
- /// </summary>
- private readonly List<IDisposable> _disposableParts = new List<IDisposable>();
-
- /// <summary>
- /// The _protobuf serializer initialized
- /// </summary>
- private bool _protobufSerializerInitialized;
- /// <summary>
- /// The _protobuf serializer sync lock
- /// </summary>
- private object _protobufSerializerSyncLock = new object();
- /// <summary>
- /// Gets a dynamically compiled generated serializer that can serialize protocontracts without reflection
- /// </summary>
- private DynamicProtobufSerializer _protobufSerializer;
- /// <summary>
- /// Gets the protobuf serializer.
- /// </summary>
- /// <value>The protobuf serializer.</value>
- public DynamicProtobufSerializer ProtobufSerializer
- {
- get
- {
- // Lazy load
- LazyInitializer.EnsureInitialized(ref _protobufSerializer, ref _protobufSerializerInitialized, ref _protobufSerializerSyncLock, () => DynamicProtobufSerializer.Create(AllTypes));
- return _protobufSerializer;
- }
- private set
- {
- _protobufSerializer = value;
-
- if (value == null)
- {
- _protobufSerializerInitialized = false;
- }
- }
- }
-
- /// <summary>
/// Gets the UDP server port number.
/// This can't be configurable because then the user would have to configure their client to discover the server.
/// </summary>
@@ -301,42 +246,40 @@ namespace MediaBrowser.Common.Kernel
protected IApplicationHost ApplicationHost { get; private set; }
/// <summary>
- /// Gets or sets the task manager.
- /// </summary>
- /// <value>The task manager.</value>
- protected ITaskManager TaskManager { get; set; }
-
- /// <summary>
- /// Gets the assemblies.
+ /// The _XML serializer
/// </summary>
- /// <value>The assemblies.</value>
- protected Assembly[] Assemblies { get; private set; }
-
- /// <summary>
- /// Gets all types.
- /// </summary>
- /// <value>All types.</value>
- public Type[] AllTypes { get; private set; }
+ private readonly IXmlSerializer _xmlSerializer;
/// <summary>
/// Initializes a new instance of the <see cref="BaseKernel{TApplicationPathsType}" /> class.
/// </summary>
/// <param name="appHost">The app host.</param>
+ /// <param name="appPaths">The app paths.</param>
+ /// <param name="xmlSerializer">The XML serializer.</param>
/// <param name="logger">The logger.</param>
/// <exception cref="System.ArgumentNullException">isoManager</exception>
- protected BaseKernel(IApplicationHost appHost, ILogger logger)
+ protected BaseKernel(IApplicationHost appHost, TApplicationPathsType appPaths, IXmlSerializer xmlSerializer, ILogger logger)
{
if (appHost == null)
{
throw new ArgumentNullException("appHost");
}
-
+ if (appPaths == null)
+ {
+ throw new ArgumentNullException("appPaths");
+ }
+ if (xmlSerializer == null)
+ {
+ throw new ArgumentNullException("xmlSerializer");
+ }
if (logger == null)
{
throw new ArgumentNullException("logger");
}
+ ApplicationPaths = appPaths;
ApplicationHost = appHost;
+ _xmlSerializer = xmlSerializer;
Logger = logger;
}
@@ -344,14 +287,12 @@ namespace MediaBrowser.Common.Kernel
/// Initializes the Kernel
/// </summary>
/// <returns>Task.</returns>
- public async Task Init()
+ public Task Init()
{
- ApplicationPaths = new TApplicationPathsType();
-
IsFirstRun = !File.Exists(ApplicationPaths.SystemConfigurationFilePath);
// Performs initializations that can be reloaded at anytime
- await Reload().ConfigureAwait(false);
+ return Reload();
}
/// <summary>
@@ -377,7 +318,6 @@ namespace MediaBrowser.Common.Kernel
{
// Set these to null so that they can be lazy loaded again
Configuration = null;
- ProtobufSerializer = null;
ReloadLogger();
@@ -388,14 +328,12 @@ namespace MediaBrowser.Common.Kernel
await OnConfigurationLoaded().ConfigureAwait(false);
- DisposeTaskManager();
- TaskManager = new TaskManager(Logger);
+ FindParts();
- Logger.Info("Loading Plugins");
- await ReloadComposableParts().ConfigureAwait(false);
+ await OnComposablePartsLoaded().ConfigureAwait(false);
DisposeTcpManager();
- TcpManager = new TcpManager(ApplicationHost, this, ApplicationHost.Resolve<INetworkManager>(), Logger);
+ TcpManager = (TcpManager)ApplicationHost.CreateInstance(typeof(TcpManager));
}
/// <summary>
@@ -418,183 +356,13 @@ namespace MediaBrowser.Common.Kernel
}
/// <summary>
- /// Uses MEF to locate plugins
- /// Subclasses can use this to locate types within plugins
- /// </summary>
- /// <returns>Task.</returns>
- private async Task ReloadComposableParts()
- {
- _failedPluginAssemblies.Clear();
-
- DisposeComposableParts();
-
- Assemblies = GetComposablePartAssemblies().ToArray();
-
- AllTypes = Assemblies.SelectMany(GetTypes).ToArray();
-
- ComposeParts(AllTypes);
-
- await OnComposablePartsLoaded().ConfigureAwait(false);
- }
-
- /// <summary>
- /// Composes the parts.
- /// </summary>
- /// <param name="allTypes">All types.</param>
- private void ComposeParts(IEnumerable<Type> allTypes)
- {
- var concreteTypes = allTypes.Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType).ToArray();
-
- RegisterExportedValues();
-
- FindParts(concreteTypes);
- }
-
- /// <summary>
/// Composes the parts with ioc container.
/// </summary>
- /// <param name="allTypes">All types.</param>
- protected virtual void FindParts(Type[] allTypes)
- {
- RestServices = GetExports<IRestfulService>(allTypes);
- WebSocketListeners = GetExports<IWebSocketListener>(allTypes);
- Plugins = GetExports<IPlugin>(allTypes);
-
- var tasks = GetExports<IScheduledTask>(allTypes, false);
-
- TaskManager.AddTasks(tasks);
- }
-
- /// <summary>
- /// Gets the exports.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="allTypes">All types.</param>
- /// <param name="manageLiftime">if set to <c>true</c> [manage liftime].</param>
- /// <returns>IEnumerable{``0}.</returns>
- protected IEnumerable<T> GetExports<T>(Type[] allTypes, bool manageLiftime = true)
- {
- var currentType = typeof(T);
-
- Logger.Info("Composing instances of " + currentType.Name);
-
- var parts = allTypes.Where(currentType.IsAssignableFrom).Select(Instantiate).Cast<T>().ToArray();
-
- if (manageLiftime)
- {
- _disposableParts.AddRange(parts.OfType<IDisposable>());
- }
-
- return parts;
- }
-
- /// <summary>
- /// Instantiates the specified type.
- /// </summary>
- /// <param name="type">The type.</param>
- /// <returns>System.Object.</returns>
- private object Instantiate(Type type)
- {
- return ApplicationHost.CreateInstance(type);
- }
-
- /// <summary>
- /// Composes the exported values.
- /// </summary>
- /// <param name="container">The container.</param>
- protected virtual void RegisterExportedValues()
+ protected virtual void FindParts()
{
- ApplicationHost.RegisterSingleInstance<IKernel>(this);
- ApplicationHost.RegisterSingleInstance(TaskManager);
- }
-
- /// <summary>
- /// Gets the composable part assemblies.
- /// </summary>
- /// <returns>IEnumerable{Assembly}.</returns>
- protected virtual IEnumerable<Assembly> GetComposablePartAssemblies()
- {
- // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that
- // This will prevent the .dll file from getting locked, and allow us to replace it when needed
- var pluginAssemblies = Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly)
- .Select(file =>
- {
- try
- {
- return Assembly.Load(File.ReadAllBytes((file)));
- }
- catch (Exception ex)
- {
- _failedPluginAssemblies.Add(file);
- Logger.ErrorException("Error loading {0}", ex, file);
- return null;
- }
-
- }).Where(a => a != null);
-
- foreach (var pluginAssembly in pluginAssemblies)
- {
- yield return pluginAssembly;
- }
-
- var runningDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
- var corePluginDirectory = Path.Combine(runningDirectory, "CorePlugins");
-
- // This will prevent the .dll file from getting locked, and allow us to replace it when needed
- pluginAssemblies = Directory.EnumerateFiles(corePluginDirectory, "*.dll", SearchOption.TopDirectoryOnly)
- .Select(file =>
- {
- try
- {
- return Assembly.Load(File.ReadAllBytes((file)));
- }
- catch (Exception ex)
- {
- _failedPluginAssemblies.Add(file);
- Logger.ErrorException("Error loading {0}", ex, file);
- return null;
- }
-
- }).Where(a => a != null);
-
- foreach (var pluginAssembly in pluginAssemblies)
- {
- yield return pluginAssembly;
- }
-
- // Include composable parts in the Model assembly
- yield return typeof(SystemInfo).Assembly;
-
- // Include composable parts in the Common assembly
- yield return Assembly.GetExecutingAssembly();
-
- // Include composable parts in the subclass assembly
- yield return GetType().Assembly;
- }
-
- /// <summary>
- /// Gets a list of types within an assembly
- /// This will handle situations that would normally throw an exception - such as a type within the assembly that depends on some other non-existant reference
- /// </summary>
- /// <param name="assembly">The assembly.</param>
- /// <returns>IEnumerable{Type}.</returns>
- /// <exception cref="System.ArgumentNullException">assembly</exception>
- private static IEnumerable<Type> GetTypes(Assembly assembly)
- {
- if (assembly == null)
- {
- throw new ArgumentNullException("assembly");
- }
-
- try
- {
- return assembly.GetTypes();
- }
- catch (ReflectionTypeLoadException ex)
- {
- // If it fails we can still get a list of the Types it was able to resolve
- return ex.Types.Where(t => t != null);
- }
+ RestServices = ApplicationHost.GetExports<IRestfulService>();
+ WebSocketListeners = ApplicationHost.GetExports<IWebSocketListener>();
+ Plugins = ApplicationHost.GetExports<IPlugin>();
}
/// <summary>
@@ -612,7 +380,7 @@ namespace MediaBrowser.Common.Kernel
try
{
- plugin.Initialize(this, Logger);
+ plugin.Initialize(this, _xmlSerializer, Logger);
Logger.Info("{0} {1} initialized.", plugin.Name, plugin.Version);
}
@@ -654,12 +422,7 @@ namespace MediaBrowser.Common.Kernel
if (dispose)
{
DisposeTcpManager();
- DisposeTaskManager();
DisposeHttpManager();
-
- DisposeComposableParts();
-
- _disposableParts.Clear();
}
}
@@ -676,18 +439,6 @@ namespace MediaBrowser.Common.Kernel
}
/// <summary>
- /// Disposes the task manager.
- /// </summary>
- private void DisposeTaskManager()
- {
- if (TaskManager != null)
- {
- TaskManager.Dispose();
- TaskManager = null;
- }
- }
-
- /// <summary>
/// Disposes the HTTP manager.
/// </summary>
private void DisposeHttpManager()
@@ -700,17 +451,6 @@ namespace MediaBrowser.Common.Kernel
}
/// <summary>
- /// Disposes all objects gathered through MEF composable parts
- /// </summary>
- protected virtual void DisposeComposableParts()
- {
- foreach (var part in _disposableParts)
- {
- part.Dispose();
- }
- }
-
- /// <summary>
/// Gets the current application version
/// </summary>
/// <value>The application version.</value>
@@ -761,7 +501,7 @@ namespace MediaBrowser.Common.Kernel
IsNetworkDeployed = ApplicationHost.CanSelfUpdate,
WebSocketPortNumber = TcpManager.WebSocketPortNumber,
SupportsNativeWebSocket = TcpManager.SupportsNativeWebSocket,
- FailedPluginAssemblies = FailedPluginAssemblies.ToArray()
+ FailedPluginAssemblies = ApplicationHost.FailedAssemblies.ToArray()
};
}
@@ -777,7 +517,7 @@ namespace MediaBrowser.Common.Kernel
{
lock (_configurationSaveLock)
{
- XmlSerializer.SerializeToFile(Configuration, ApplicationPaths.SystemConfigurationFilePath);
+ _xmlSerializer.SerializeToFile(Configuration, ApplicationPaths.SystemConfigurationFilePath);
}
OnConfigurationUpdated();
@@ -787,7 +527,7 @@ namespace MediaBrowser.Common.Kernel
/// Gets the application paths.
/// </summary>
/// <value>The application paths.</value>
- BaseApplicationPaths IKernel.ApplicationPaths
+ IApplicationPaths IKernel.ApplicationPaths
{
get { return ApplicationPaths; }
}
@@ -798,6 +538,63 @@ namespace MediaBrowser.Common.Kernel
BaseApplicationConfiguration IKernel.Configuration
{
get { return Configuration; }
+ }
+
+ /// <summary>
+ /// Reads an xml configuration file from the file system
+ /// It will immediately re-serialize and save if new serialization data is available due to property changes
+ /// </summary>
+ /// <param name="type">The type.</param>
+ /// <param name="path">The path.</param>
+ /// <returns>System.Object.</returns>
+ public object GetXmlConfiguration(Type type, string path)
+ {
+ Logger.Info("Loading {0} at {1}", type.Name, path);
+
+ object configuration;
+
+ byte[] buffer = null;
+
+ // Use try/catch to avoid the extra file system lookup using File.Exists
+ try
+ {
+ buffer = File.ReadAllBytes(path);
+
+ configuration = _xmlSerializer.DeserializeFromBytes(type, buffer);
+ }
+ catch (FileNotFoundException)
+ {
+ configuration = ApplicationHost.CreateInstance(type);
+ }
+
+ // Take the object we just got and serialize it back to bytes
+ var newBytes = _xmlSerializer.SerializeToBytes(configuration);
+
+ // If the file didn't exist before, or if something has changed, re-save
+ if (buffer == null || !buffer.SequenceEqual(newBytes))
+ {
+ Logger.Info("Saving {0} to {1}", type.Name, path);
+
+ // Save it after load in case we got new items
+ File.WriteAllBytes(path, newBytes);
+ }
+
+ return configuration;
+ }
+
+
+ /// <summary>
+ /// Reads an xml configuration file from the file system
+ /// It will immediately save the configuration after loading it, just
+ /// in case there are new serializable properties
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="path">The path.</param>
+ /// <returns>``0.</returns>
+ private T GetXmlConfiguration<T>(string path)
+ where T : class
+ {
+ return GetXmlConfiguration(typeof(T), path) as T;
}
}
}
diff --git a/MediaBrowser.Common/Kernel/IApplicationHost.cs b/MediaBrowser.Common/Kernel/IApplicationHost.cs
index fe2f00a12..4b564581b 100644
--- a/MediaBrowser.Common/Kernel/IApplicationHost.cs
+++ b/MediaBrowser.Common/Kernel/IApplicationHost.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Model.Updates;
using System;
+using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
@@ -33,6 +34,26 @@ namespace MediaBrowser.Common.Kernel
bool CanSelfUpdate { get; }
/// <summary>
+ /// Gets the failed assemblies.
+ /// </summary>
+ /// <value>The failed assemblies.</value>
+ IEnumerable<string> FailedAssemblies { get; }
+
+ /// <summary>
+ /// Gets all concrete types.
+ /// </summary>
+ /// <value>All concrete types.</value>
+ Type[] AllConcreteTypes { get; }
+
+ /// <summary>
+ /// Gets the exports.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="manageLiftime">if set to <c>true</c> [manage liftime].</param>
+ /// <returns>IEnumerable{``0}.</returns>
+ IEnumerable<T> GetExports<T>(bool manageLiftime = true);
+
+ /// <summary>
/// Checks for update.
/// </summary>
/// <returns>Task{CheckForUpdateResult}.</returns>
diff --git a/MediaBrowser.Common/Kernel/IApplicationPaths.cs b/MediaBrowser.Common/Kernel/IApplicationPaths.cs
new file mode 100644
index 000000000..abb783642
--- /dev/null
+++ b/MediaBrowser.Common/Kernel/IApplicationPaths.cs
@@ -0,0 +1,76 @@
+
+namespace MediaBrowser.Common.Kernel
+{
+ /// <summary>
+ /// Interface IApplicationPaths
+ /// </summary>
+ public interface IApplicationPaths
+ {
+ /// <summary>
+ /// Gets the path to the program data folder
+ /// </summary>
+ /// <value>The program data path.</value>
+ string ProgramDataPath { get; }
+
+ /// <summary>
+ /// Gets the folder path to the data directory
+ /// </summary>
+ /// <value>The data directory.</value>
+ string DataPath { get; }
+
+ /// <summary>
+ /// Gets the image cache path.
+ /// </summary>
+ /// <value>The image cache path.</value>
+ string ImageCachePath { get; }
+
+ /// <summary>
+ /// Gets the path to the plugin directory
+ /// </summary>
+ /// <value>The plugins path.</value>
+ string PluginsPath { get; }
+
+ /// <summary>
+ /// Gets the path to the plugin configurations directory
+ /// </summary>
+ /// <value>The plugin configurations path.</value>
+ string PluginConfigurationsPath { get; }
+
+ /// <summary>
+ /// Gets the path to where temporary update files will be stored
+ /// </summary>
+ /// <value>The plugin configurations path.</value>
+ string TempUpdatePath { get; }
+
+ /// <summary>
+ /// Gets the path to the log directory
+ /// </summary>
+ /// <value>The log directory path.</value>
+ string LogDirectoryPath { get; }
+
+ /// <summary>
+ /// Gets the path to the application configuration root directory
+ /// </summary>
+ /// <value>The configuration directory path.</value>
+ string ConfigurationDirectoryPath { get; }
+
+ /// <summary>
+ /// Gets the path to the system configuration file
+ /// </summary>
+ /// <value>The system configuration file path.</value>
+ string SystemConfigurationFilePath { get; }
+
+ /// <summary>
+ /// Gets the folder path to the cache directory
+ /// </summary>
+ /// <value>The cache directory.</value>
+ string CachePath { get; }
+
+ /// <summary>
+ /// Gets the folder path to the temp directory within the cache folder
+ /// </summary>
+ /// <value>The temp directory.</value>
+ string TempDirectory { get; }
+ }
+
+}
diff --git a/MediaBrowser.Common/Kernel/IKernel.cs b/MediaBrowser.Common/Kernel/IKernel.cs
index 253368f4f..fb629a24d 100644
--- a/MediaBrowser.Common/Kernel/IKernel.cs
+++ b/MediaBrowser.Common/Kernel/IKernel.cs
@@ -1,6 +1,5 @@
using MediaBrowser.Common.Net;
using MediaBrowser.Common.Plugins;
-using MediaBrowser.Common.Serialization;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.System;
using System;
@@ -18,7 +17,7 @@ namespace MediaBrowser.Common.Kernel
/// Gets the application paths.
/// </summary>
/// <value>The application paths.</value>
- BaseApplicationPaths ApplicationPaths { get; }
+ IApplicationPaths ApplicationPaths { get; }
/// <summary>
/// Gets the configuration.
@@ -33,12 +32,6 @@ namespace MediaBrowser.Common.Kernel
KernelContext KernelContext { get; }
/// <summary>
- /// Gets the protobuf serializer.
- /// </summary>
- /// <value>The protobuf serializer.</value>
- DynamicProtobufSerializer ProtobufSerializer { get; }
-
- /// <summary>
/// Inits this instance.
/// </summary>
/// <returns>Task.</returns>
@@ -156,5 +149,13 @@ namespace MediaBrowser.Common.Kernel
/// Notifies the pending restart.
/// </summary>
void NotifyPendingRestart();
+
+ /// <summary>
+ /// Gets the XML configuration.
+ /// </summary>
+ /// <param name="type">The type.</param>
+ /// <param name="path">The path.</param>
+ /// <returns>System.Object.</returns>
+ object GetXmlConfiguration(Type type, string path);
}
}
diff --git a/MediaBrowser.Common/Kernel/TcpManager.cs b/MediaBrowser.Common/Kernel/TcpManager.cs
index 9a998823f..c04b77599 100644
--- a/MediaBrowser.Common/Kernel/TcpManager.cs
+++ b/MediaBrowser.Common/Kernel/TcpManager.cs
@@ -1,5 +1,4 @@
using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Serialization;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Logging;
using System;
@@ -14,6 +13,7 @@ using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Common.Kernel
{
@@ -36,6 +36,12 @@ namespace MediaBrowser.Common.Kernel
private IHttpServer HttpServer { get; set; }
/// <summary>
+ /// Gets or sets the json serializer.
+ /// </summary>
+ /// <value>The json serializer.</value>
+ private IJsonSerializer _jsonSerializer;
+
+ /// <summary>
/// This subscribes to HttpListener requests and finds the appropriate BaseHandler to process it
/// </summary>
/// <value>The HTTP listener.</value>
@@ -96,8 +102,10 @@ namespace MediaBrowser.Common.Kernel
/// <param name="applicationHost">The application host.</param>
/// <param name="kernel">The kernel.</param>
/// <param name="networkManager">The network manager.</param>
+ /// <param name="jsonSerializer">The json serializer.</param>
/// <param name="logger">The logger.</param>
- public TcpManager(IApplicationHost applicationHost, IKernel kernel, INetworkManager networkManager, ILogger logger)
+ /// <exception cref="System.ArgumentNullException">applicationHost</exception>
+ public TcpManager(IApplicationHost applicationHost, IKernel kernel, INetworkManager networkManager, IJsonSerializer jsonSerializer, ILogger logger)
{
if (applicationHost == null)
{
@@ -111,12 +119,17 @@ namespace MediaBrowser.Common.Kernel
{
throw new ArgumentNullException("networkManager");
}
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
if (logger == null)
{
throw new ArgumentNullException("logger");
}
_logger = logger;
+ _jsonSerializer = jsonSerializer;
_kernel = kernel;
_applicationHost = applicationHost;
_networkManager = networkManager;
@@ -203,7 +216,7 @@ namespace MediaBrowser.Common.Kernel
/// <param name="e">The <see cref="WebSocketConnectEventArgs" /> instance containing the event data.</param>
void HttpServer_WebSocketConnected(object sender, WebSocketConnectEventArgs e)
{
- var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, ProcessWebSocketMessageReceived, _logger);
+ var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, ProcessWebSocketMessageReceived, _jsonSerializer, _logger);
_webSocketConnections.Add(connection);
}
@@ -342,7 +355,7 @@ namespace MediaBrowser.Common.Kernel
_logger.Info("Sending web socket message {0}", messageType);
var message = new WebSocketMessage<T> { MessageType = messageType, Data = dataFunction() };
- var bytes = JsonSerializer.SerializeToBytes(message);
+ var bytes = _jsonSerializer.SerializeToBytes(message);
var tasks = connections.Select(s => Task.Run(() =>
{
diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj
index 28789a816..f9147141d 100644
--- a/MediaBrowser.Common/MediaBrowser.Common.csproj
+++ b/MediaBrowser.Common/MediaBrowser.Common.csproj
@@ -38,10 +38,6 @@
</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
- <Reference Include="protobuf-net, Version=2.0.0.621, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\protobuf-net.2.0.0.621\lib\net40\protobuf-net.dll</HintPath>
- </Reference>
<Reference Include="ServiceStack, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.3.9.37\lib\net35\ServiceStack.dll</HintPath>
@@ -75,14 +71,12 @@
<HintPath>..\packages\ServiceStack.Text.3.9.37\lib\net35\ServiceStack.Text.dll</HintPath>
</Reference>
<Reference Include="System" />
- <Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Net" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Web" />
<Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\SharedVersion.cs">
@@ -98,8 +92,8 @@
<Compile Include="IO\IIsoMount.cs" />
<Compile Include="IO\ProgressStream.cs" />
<Compile Include="IO\StreamDefaults.cs" />
- <Compile Include="Kernel\BaseApplicationPaths.cs" />
<Compile Include="Kernel\BasePeriodicWebSocketListener.cs" />
+ <Compile Include="Kernel\IApplicationPaths.cs" />
<Compile Include="Kernel\IWebSocketListener.cs" />
<Compile Include="Kernel\IApplicationHost.cs" />
<Compile Include="Kernel\IKernel.cs" />
@@ -116,7 +110,6 @@
<Compile Include="Net\IWebSocket.cs" />
<Compile Include="Net\IWebSocketServer.cs" />
<Compile Include="Net\MimeTypes.cs" />
- <Compile Include="Net\NativeWebSocket.cs" />
<Compile Include="Net\UdpMessageReceivedEventArgs.cs" />
<Compile Include="Net\WebSocketConnectEventArgs.cs" />
<Compile Include="Net\WebSocketConnection.cs" />
@@ -130,26 +123,18 @@
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="ScheduledTasks\ITaskManager.cs" />
- <Compile Include="ScheduledTasks\TaskManager.cs" />
- <Compile Include="ScheduledTasks\Tasks\ReloadLoggerTask.cs" />
+ <Compile Include="ScheduledTasks\ITaskTrigger.cs" />
<Compile Include="ScheduledTasks\ScheduledTaskHelpers.cs" />
<Compile Include="ScheduledTasks\StartupTrigger.cs" />
<Compile Include="ScheduledTasks\SystemEventTrigger.cs" />
- <Compile Include="ScheduledTasks\Tasks\SystemUpdateTask.cs" />
- <Compile Include="Serialization\DynamicProtobufSerializer.cs" />
- <Compile Include="Serialization\JsonSerializer.cs" />
<Compile Include="Kernel\BaseKernel.cs" />
<Compile Include="Kernel\KernelContext.cs" />
<Compile Include="Net\Handlers\BaseHandler.cs" />
<Compile Include="Net\Handlers\BaseSerializationHandler.cs" />
<Compile Include="Plugins\BasePlugin.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Serialization\XmlSerializer.cs" />
<Compile Include="ScheduledTasks\BaseScheduledTask.cs" />
- <Compile Include="ScheduledTasks\BaseTaskTrigger.cs" />
<Compile Include="ScheduledTasks\DailyTrigger.cs" />
- <Compile Include="ScheduledTasks\Tasks\DeleteCacheFileTask.cs" />
- <Compile Include="ScheduledTasks\Tasks\DeleteLogFileTask.cs" />
<Compile Include="ScheduledTasks\IntervalTrigger.cs" />
<Compile Include="ScheduledTasks\IScheduledTask.cs" />
<Compile Include="ScheduledTasks\WeeklyTrigger.cs" />
diff --git a/MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs b/MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs
index 293cb6e98..a00152d78 100644
--- a/MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs
+++ b/MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs
@@ -1,6 +1,5 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Serialization;
using System;
using System.IO;
using System.Threading.Tasks;
@@ -104,15 +103,15 @@ namespace MediaBrowser.Common.Net.Handlers
{
return Task.Run(() =>
{
- switch (SerializationFormat)
- {
- case SerializationFormat.Protobuf:
- Kernel.ProtobufSerializer.SerializeToStream(_objectToSerialize, stream);
- break;
- default:
- JsonSerializer.SerializeToStream(_objectToSerialize, stream);
- break;
- }
+ //switch (SerializationFormat)
+ //{
+ // case SerializationFormat.Protobuf:
+ // Kernel.ProtobufSerializer.SerializeToStream(_objectToSerialize, stream);
+ // break;
+ // default:
+ // JsonSerializer.SerializeToStream(_objectToSerialize, stream);
+ // break;
+ //}
});
}
}
diff --git a/MediaBrowser.Common/Net/IWebSocket.cs b/MediaBrowser.Common/Net/IWebSocket.cs
index 96299e3b2..3fd4b1241 100644
--- a/MediaBrowser.Common/Net/IWebSocket.cs
+++ b/MediaBrowser.Common/Net/IWebSocket.cs
@@ -20,7 +20,7 @@ namespace MediaBrowser.Common.Net
/// Gets or sets the receive action.
/// </summary>
/// <value>The receive action.</value>
- Action<WebSocketMessageInfo> OnReceiveDelegate { get; set; }
+ Action<byte[]> OnReceiveDelegate { get; set; }
/// <summary>
/// Sends the async.
diff --git a/MediaBrowser.Common/Net/WebSocketConnection.cs b/MediaBrowser.Common/Net/WebSocketConnection.cs
index ab691c823..6b22ef78e 100644
--- a/MediaBrowser.Common/Net/WebSocketConnection.cs
+++ b/MediaBrowser.Common/Net/WebSocketConnection.cs
@@ -1,7 +1,7 @@
-using MediaBrowser.Common.Serialization;
+using System.IO;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
using System;
-using System.Net;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
@@ -39,13 +39,20 @@ namespace MediaBrowser.Common.Net
private readonly ILogger _logger;
/// <summary>
+ /// The _json serializer
+ /// </summary>
+ private readonly IJsonSerializer _jsonSerializer;
+
+ /// <summary>
/// Initializes a new instance of the <see cref="WebSocketConnection" /> class.
/// </summary>
/// <param name="socket">The socket.</param>
/// <param name="remoteEndPoint">The remote end point.</param>
/// <param name="receiveAction">The receive action.</param>
+ /// <param name="jsonSerializer">The json serializer.</param>
+ /// <param name="logger">The logger.</param>
/// <exception cref="System.ArgumentNullException">socket</exception>
- public WebSocketConnection(IWebSocket socket, string remoteEndPoint, Action<WebSocketMessageInfo> receiveAction, ILogger logger)
+ public WebSocketConnection(IWebSocket socket, string remoteEndPoint, Action<WebSocketMessageInfo> receiveAction, IJsonSerializer jsonSerializer, ILogger logger)
{
if (socket == null)
{
@@ -59,11 +66,16 @@ namespace MediaBrowser.Common.Net
{
throw new ArgumentNullException("receiveAction");
}
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
if (logger == null)
{
throw new ArgumentNullException("logger");
}
+ _jsonSerializer = jsonSerializer;
_socket = socket;
_socket.OnReceiveDelegate = info => OnReceive(info, receiveAction);
RemoteEndPoint = remoteEndPoint;
@@ -73,12 +85,19 @@ namespace MediaBrowser.Common.Net
/// <summary>
/// Called when [receive].
/// </summary>
- /// <param name="info">The info.</param>
+ /// <param name="bytes">The bytes.</param>
/// <param name="callback">The callback.</param>
- private void OnReceive(WebSocketMessageInfo info, Action<WebSocketMessageInfo> callback)
+ private void OnReceive(byte[] bytes, Action<WebSocketMessageInfo> callback)
{
try
{
+ WebSocketMessageInfo info;
+
+ using (var memoryStream = new MemoryStream(bytes))
+ {
+ info = _jsonSerializer.DeserializeFromStream<WebSocketMessageInfo>(memoryStream);
+ }
+
info.Connection = this;
callback(info);
@@ -103,8 +122,8 @@ namespace MediaBrowser.Common.Net
{
throw new ArgumentNullException("message");
}
-
- var bytes = JsonSerializer.SerializeToBytes(message);
+
+ var bytes = _jsonSerializer.SerializeToBytes(message);
return SendAsync(bytes, cancellationToken);
}
diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs
index d089aa1b3..dad3867fc 100644
--- a/MediaBrowser.Common/Plugins/BasePlugin.cs
+++ b/MediaBrowser.Common/Plugins/BasePlugin.cs
@@ -1,5 +1,4 @@
using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Serialization;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Plugins;
using System;
@@ -7,6 +6,7 @@ using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
+using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Common.Plugins
{
@@ -188,7 +188,7 @@ namespace MediaBrowser.Common.Plugins
get
{
// Lazy load
- LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationInitialized, ref _configurationSyncLock, () => XmlSerializer.GetXmlConfiguration(ConfigurationType, ConfigurationFilePath, Logger) as TConfigurationType);
+ LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationInitialized, ref _configurationSyncLock, () => Kernel.GetXmlConfiguration(ConfigurationType, ConfigurationFilePath) as TConfigurationType);
return _configuration;
}
protected set
@@ -270,25 +270,37 @@ namespace MediaBrowser.Common.Plugins
public ILogger Logger { get; private set; }
/// <summary>
+ /// Gets the XML serializer.
+ /// </summary>
+ /// <value>The XML serializer.</value>
+ protected IXmlSerializer XmlSerializer { get; private set; }
+
+ /// <summary>
/// Starts the plugin.
/// </summary>
/// <param name="kernel">The kernel.</param>
+ /// <param name="xmlSerializer">The XML serializer.</param>
/// <param name="logger">The logger.</param>
/// <exception cref="System.ArgumentNullException">kernel</exception>
- public void Initialize(IKernel kernel, ILogger logger)
+ public void Initialize(IKernel kernel, IXmlSerializer xmlSerializer, ILogger logger)
{
if (kernel == null)
{
throw new ArgumentNullException("kernel");
}
+ if (xmlSerializer == null)
+ {
+ throw new ArgumentNullException("xmlSerializer");
+ }
+
if (logger == null)
{
throw new ArgumentNullException("logger");
}
-
+
+ XmlSerializer = xmlSerializer;
Logger = logger;
-
Kernel = kernel;
if (kernel.KernelContext == KernelContext.Server)
diff --git a/MediaBrowser.Common/Plugins/IPlugin.cs b/MediaBrowser.Common/Plugins/IPlugin.cs
index 198678491..1b25cdcb1 100644
--- a/MediaBrowser.Common/Plugins/IPlugin.cs
+++ b/MediaBrowser.Common/Plugins/IPlugin.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Common.Kernel;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Plugins;
+using MediaBrowser.Model.Serialization;
using System;
namespace MediaBrowser.Common.Plugins
@@ -107,9 +108,10 @@ namespace MediaBrowser.Common.Plugins
/// Starts the plugin.
/// </summary>
/// <param name="kernel">The kernel.</param>
+ /// <param name="xmlSerializer">The XML serializer.</param>
/// <param name="logger">The logger.</param>
/// <exception cref="System.ArgumentNullException">kernel</exception>
- void Initialize(IKernel kernel, ILogger logger);
+ void Initialize(IKernel kernel, IXmlSerializer xmlSerializer, ILogger logger);
/// <summary>
/// Disposes the plugins. Undos all actions performed during Init.
diff --git a/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs b/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs
index 845faf31a..09ceaa9ae 100644
--- a/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs
+++ b/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs
@@ -1,6 +1,5 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Serialization;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Tasks;
using System;
@@ -90,7 +89,7 @@ namespace MediaBrowser.Common.ScheduledTasks
{
try
{
- return JsonSerializer.DeserializeFromFile<TaskResult>(HistoryFilePath);
+ return TaskManager.GetLastExecutionResult(this);
}
catch (IOException)
{
@@ -110,74 +109,6 @@ namespace MediaBrowser.Common.ScheduledTasks
}
/// <summary>
- /// The _scheduled tasks data directory
- /// </summary>
- private string _scheduledTasksDataDirectory;
- /// <summary>
- /// Gets the scheduled tasks data directory.
- /// </summary>
- /// <value>The scheduled tasks data directory.</value>
- private string ScheduledTasksDataDirectory
- {
- get
- {
- if (_scheduledTasksDataDirectory == null)
- {
- _scheduledTasksDataDirectory = Path.Combine(Kernel.ApplicationPaths.DataPath, "ScheduledTasks");
-
- if (!Directory.Exists(_scheduledTasksDataDirectory))
- {
- Directory.CreateDirectory(_scheduledTasksDataDirectory);
- }
- }
- return _scheduledTasksDataDirectory;
- }
- }
-
- /// <summary>
- /// The _scheduled tasks configuration directory
- /// </summary>
- private string _scheduledTasksConfigurationDirectory;
- /// <summary>
- /// Gets the scheduled tasks configuration directory.
- /// </summary>
- /// <value>The scheduled tasks configuration directory.</value>
- private string ScheduledTasksConfigurationDirectory
- {
- get
- {
- if (_scheduledTasksConfigurationDirectory == null)
- {
- _scheduledTasksConfigurationDirectory = Path.Combine(Kernel.ApplicationPaths.ConfigurationDirectoryPath, "ScheduledTasks");
-
- if (!Directory.Exists(_scheduledTasksConfigurationDirectory))
- {
- Directory.CreateDirectory(_scheduledTasksConfigurationDirectory);
- }
- }
- return _scheduledTasksConfigurationDirectory;
- }
- }
-
- /// <summary>
- /// Gets the configuration file path.
- /// </summary>
- /// <value>The configuration file path.</value>
- private string ConfigurationFilePath
- {
- get { return Path.Combine(ScheduledTasksConfigurationDirectory, Id + ".js"); }
- }
-
- /// <summary>
- /// Gets the history file path.
- /// </summary>
- /// <value>The history file path.</value>
- private string HistoryFilePath
- {
- get { return Path.Combine(ScheduledTasksDataDirectory, Id + ".js"); }
- }
-
- /// <summary>
/// Gets the current cancellation token
/// </summary>
/// <value>The current cancellation token source.</value>
@@ -217,7 +148,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// <summary>
/// The _triggers
/// </summary>
- private IEnumerable<BaseTaskTrigger> _triggers;
+ private IEnumerable<ITaskTrigger> _triggers;
/// <summary>
/// The _triggers initialized
/// </summary>
@@ -231,24 +162,11 @@ namespace MediaBrowser.Common.ScheduledTasks
/// </summary>
/// <value>The triggers.</value>
/// <exception cref="System.ArgumentNullException">value</exception>
- public IEnumerable<BaseTaskTrigger> Triggers
+ public IEnumerable<ITaskTrigger> Triggers
{
get
{
- LazyInitializer.EnsureInitialized(ref _triggers, ref _triggersInitialized, ref _triggersSyncLock, () =>
- {
- try
- {
- return JsonSerializer.DeserializeFromFile<IEnumerable<TaskTriggerInfo>>(ConfigurationFilePath)
- .Select(ScheduledTaskHelpers.GetTrigger)
- .ToList();
- }
- catch (IOException)
- {
- // File doesn't exist. No biggie. Return defaults.
- return GetDefaultTriggers();
- }
- });
+ LazyInitializer.EnsureInitialized(ref _triggers, ref _triggersInitialized, ref _triggersSyncLock, () => TaskManager.LoadTriggers(this));
return _triggers;
}
@@ -271,7 +189,7 @@ namespace MediaBrowser.Common.ScheduledTasks
ReloadTriggerEvents(false);
- JsonSerializer.SerializeToFile(_triggers.Select(ScheduledTaskHelpers.GetTriggerInfo), ConfigurationFilePath);
+ TaskManager.SaveTriggers(this, _triggers);
}
}
@@ -279,7 +197,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// Creates the triggers that define when the task will run
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- protected abstract IEnumerable<BaseTaskTrigger> GetDefaultTriggers();
+ public abstract IEnumerable<ITaskTrigger> GetDefaultTriggers();
/// <summary>
/// Returns the task to be executed
@@ -314,6 +232,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// The _id
/// </summary>
private Guid? _id;
+
/// <summary>
/// Gets the unique id.
/// </summary>
@@ -352,13 +271,19 @@ namespace MediaBrowser.Common.ScheduledTasks
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
- void trigger_Triggered(object sender, EventArgs e)
+ async void trigger_Triggered(object sender, EventArgs e)
{
- var trigger = (BaseTaskTrigger)sender;
+ var trigger = (ITaskTrigger)sender;
Logger.Info("{0} fired for task: {1}", trigger.GetType().Name, Name);
+ trigger.Stop();
+
TaskManager.QueueScheduledTask(this);
+
+ await Task.Delay(1000).ConfigureAwait(false);
+
+ trigger.Start(false);
}
/// <summary>
@@ -404,10 +329,9 @@ namespace MediaBrowser.Common.ScheduledTasks
status = TaskCompletionStatus.Failed;
}
+ var startTime = CurrentExecutionStartTime;
var endTime = DateTime.UtcNow;
- LogResult(endTime, status);
-
Kernel.TcpManager.SendWebSocketMessage("ScheduledTaskEndExecute", LastExecutionResult);
progress.ProgressChanged -= progress_ProgressChanged;
@@ -415,33 +339,7 @@ namespace MediaBrowser.Common.ScheduledTasks
CurrentCancellationTokenSource = null;
CurrentProgress = null;
- TaskManager.OnTaskCompleted(this);
- }
-
- /// <summary>
- /// Logs the result.
- /// </summary>
- /// <param name="endTime">The end time.</param>
- /// <param name="status">The status.</param>
- private void LogResult(DateTime endTime, TaskCompletionStatus status)
- {
- var startTime = CurrentExecutionStartTime;
- 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, HistoryFilePath);
-
- LastExecutionResult = result;
+ TaskManager.OnTaskCompleted(this, startTime, endTime, status);
}
/// <summary>
@@ -501,7 +399,7 @@ namespace MediaBrowser.Common.ScheduledTasks
if (State == TaskState.Running)
{
- LogResult(DateTime.UtcNow, TaskCompletionStatus.Aborted);
+ TaskManager.OnTaskCompleted(this, CurrentExecutionStartTime, DateTime.UtcNow, TaskCompletionStatus.Aborted);
}
if (CurrentCancellationTokenSource != null)
@@ -519,7 +417,7 @@ namespace MediaBrowser.Common.ScheduledTasks
foreach (var trigger in Triggers)
{
trigger.Triggered -= trigger_Triggered;
- trigger.Dispose();
+ trigger.Stop();
}
}
}
diff --git a/MediaBrowser.Common/ScheduledTasks/BaseTaskTrigger.cs b/MediaBrowser.Common/ScheduledTasks/BaseTaskTrigger.cs
deleted file mode 100644
index ed302ed39..000000000
--- a/MediaBrowser.Common/ScheduledTasks/BaseTaskTrigger.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using System;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Common.ScheduledTasks
-{
- /// <summary>
- /// Use to indicate that a scheduled task should run
- /// </summary>
- public abstract class BaseTaskTrigger : IDisposable
- {
- /// <summary>
- /// Fires when the trigger condition is satisfied and the task should run
- /// </summary>
- internal event EventHandler<EventArgs> Triggered;
-
- /// <summary>
- /// Called when [triggered].
- /// </summary>
- protected async void OnTriggered()
- {
- Stop();
-
- if (Triggered != null)
- {
- Triggered(this, EventArgs.Empty);
- }
-
- await Task.Delay(1000).ConfigureAwait(false);
-
- Start(false);
- }
-
- /// <summary>
- /// Stars waiting for the trigger action
- /// </summary>
- protected internal abstract void Start(bool isApplicationStartup);
-
- /// <summary>
- /// Stops waiting for the trigger action
- /// </summary>
- protected internal abstract void Stop();
-
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources.
- /// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected virtual void Dispose(bool dispose)
- {
- if (dispose)
- {
- Stop();
- }
- }
- }
-}
diff --git a/MediaBrowser.Common/ScheduledTasks/DailyTrigger.cs b/MediaBrowser.Common/ScheduledTasks/DailyTrigger.cs
index fb749f77c..bfecadee7 100644
--- a/MediaBrowser.Common/ScheduledTasks/DailyTrigger.cs
+++ b/MediaBrowser.Common/ScheduledTasks/DailyTrigger.cs
@@ -6,7 +6,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// <summary>
/// Represents a task trigger that fires everyday
/// </summary>
- public class DailyTrigger : BaseTaskTrigger
+ public class DailyTrigger : ITaskTrigger
{
/// <summary>
/// Get the time of day to trigger the task to run
@@ -24,7 +24,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// Stars waiting for the trigger action
/// </summary>
/// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
- protected internal override void Start(bool isApplicationStartup)
+ public void Start(bool isApplicationStartup)
{
DisposeTimer();
@@ -39,33 +39,35 @@ namespace MediaBrowser.Common.ScheduledTasks
/// <summary>
/// Stops waiting for the trigger action
/// </summary>
- protected internal override void Stop()
+ public void Stop()
{
DisposeTimer();
}
/// <summary>
- /// Disposes this instance.
+ /// Disposes the timer.
/// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected override void Dispose(bool dispose)
+ private void DisposeTimer()
{
- if (dispose)
+ if (Timer != null)
{
- DisposeTimer();
+ Timer.Dispose();
}
-
- base.Dispose(dispose);
}
/// <summary>
- /// Disposes the timer.
+ /// Occurs when [triggered].
/// </summary>
- private void DisposeTimer()
+ public event EventHandler<EventArgs> Triggered;
+
+ /// <summary>
+ /// Called when [triggered].
+ /// </summary>
+ private void OnTriggered()
{
- if (Timer != null)
+ if (Triggered != null)
{
- Timer.Dispose();
+ Triggered(this, EventArgs.Empty);
}
}
}
diff --git a/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs b/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs
index cba5fc5d0..6f3a3857f 100644
--- a/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs
+++ b/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs
@@ -14,7 +14,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// Gets the triggers.
/// </summary>
/// <value>The triggers.</value>
- IEnumerable<BaseTaskTrigger> Triggers { get; set; }
+ IEnumerable<ITaskTrigger> Triggers { get; set; }
/// <summary>
/// Gets the last execution result.
@@ -75,5 +75,11 @@ namespace MediaBrowser.Common.ScheduledTasks
/// Cancels if running.
/// </summary>
void CancelIfRunning();
+
+ /// <summary>
+ /// Gets the default triggers.
+ /// </summary>
+ /// <returns>IEnumerable{BaseTaskTrigger}.</returns>
+ IEnumerable<ITaskTrigger> GetDefaultTriggers();
}
} \ No newline at end of file
diff --git a/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs b/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs
index 430208869..42d7020e6 100644
--- a/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs
+++ b/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs
@@ -1,4 +1,5 @@
-using System;
+using MediaBrowser.Model.Tasks;
+using System;
using System.Collections.Generic;
namespace MediaBrowser.Common.ScheduledTasks
@@ -41,6 +42,30 @@ namespace MediaBrowser.Common.ScheduledTasks
/// Called when [task completed].
/// </summary>
/// <param name="task">The task.</param>
- void OnTaskCompleted(IScheduledTask task);
+ /// <param name="startTime">The start time.</param>
+ /// <param name="endTime">The end time.</param>
+ /// <param name="status">The status.</param>
+ void OnTaskCompleted(IScheduledTask task, DateTime startTime, DateTime endTime, TaskCompletionStatus status);
+
+ /// <summary>
+ /// Gets the last execution result.
+ /// </summary>
+ /// <param name="task">The task.</param>
+ /// <returns>TaskResult.</returns>
+ TaskResult GetLastExecutionResult(IScheduledTask task);
+
+ /// <summary>
+ /// Loads the triggers.
+ /// </summary>
+ /// <param name="task">The task.</param>
+ /// <returns>IEnumerable{BaseTaskTrigger}.</returns>
+ IEnumerable<ITaskTrigger> LoadTriggers(IScheduledTask task);
+
+ /// <summary>
+ /// Saves the triggers.
+ /// </summary>
+ /// <param name="task">The task.</param>
+ /// <param name="triggers">The triggers.</param>
+ void SaveTriggers(IScheduledTask task, IEnumerable<ITaskTrigger> triggers);
}
} \ No newline at end of file
diff --git a/MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs b/MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs
new file mode 100644
index 000000000..66701650e
--- /dev/null
+++ b/MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace MediaBrowser.Common.ScheduledTasks
+{
+ /// <summary>
+ /// Interface ITaskTrigger
+ /// </summary>
+ public interface ITaskTrigger
+ {
+ /// <summary>
+ /// Fires when the trigger condition is satisfied and the task should run
+ /// </summary>
+ event EventHandler<EventArgs> Triggered;
+
+ /// <summary>
+ /// Stars waiting for the trigger action
+ /// </summary>
+ /// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
+ void Start(bool isApplicationStartup);
+
+ /// <summary>
+ /// Stops waiting for the trigger action
+ /// </summary>
+ void Stop();
+ }
+} \ No newline at end of file
diff --git a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs
index 759447b10..cac6d1fa3 100644
--- a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs
+++ b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs
@@ -6,7 +6,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// <summary>
/// Represents a task trigger that runs repeatedly on an interval
/// </summary>
- public class IntervalTrigger : BaseTaskTrigger
+ public class IntervalTrigger : ITaskTrigger
{
/// <summary>
/// Gets or sets the interval.
@@ -24,7 +24,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// Stars waiting for the trigger action
/// </summary>
/// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
- protected internal override void Start(bool isApplicationStartup)
+ public void Start(bool isApplicationStartup)
{
DisposeTimer();
@@ -34,33 +34,35 @@ namespace MediaBrowser.Common.ScheduledTasks
/// <summary>
/// Stops waiting for the trigger action
/// </summary>
- protected internal override void Stop()
+ public void Stop()
{
DisposeTimer();
}
/// <summary>
- /// Disposes this instance.
+ /// Disposes the timer.
/// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected override void Dispose(bool dispose)
+ private void DisposeTimer()
{
- if (dispose)
+ if (Timer != null)
{
- DisposeTimer();
+ Timer.Dispose();
}
-
- base.Dispose(dispose);
}
/// <summary>
- /// Disposes the timer.
+ /// Occurs when [triggered].
/// </summary>
- private void DisposeTimer()
+ public event EventHandler<EventArgs> Triggered;
+
+ /// <summary>
+ /// Called when [triggered].
+ /// </summary>
+ private void OnTriggered()
{
- if (Timer != null)
+ if (Triggered != null)
{
- Timer.Dispose();
+ Triggered(this, EventArgs.Empty);
}
}
}
diff --git a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs b/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs
index 9942da17f..e67eb3626 100644
--- a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs
+++ b/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs
@@ -35,7 +35,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// </summary>
/// <param name="trigger">The trigger.</param>
/// <returns>TaskTriggerInfo.</returns>
- public static TaskTriggerInfo GetTriggerInfo(BaseTaskTrigger trigger)
+ public static TaskTriggerInfo GetTriggerInfo(ITaskTrigger trigger)
{
var info = new TaskTriggerInfo
{
@@ -81,7 +81,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// <returns>BaseTaskTrigger.</returns>
/// <exception cref="System.ArgumentNullException"></exception>
/// <exception cref="System.ArgumentException">Invalid trigger type: + info.Type</exception>
- public static BaseTaskTrigger GetTrigger(TaskTriggerInfo info)
+ public static ITaskTrigger GetTrigger(TaskTriggerInfo info)
{
if (info.Type.Equals(typeof(DailyTrigger).Name, StringComparison.OrdinalIgnoreCase))
{
diff --git a/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs b/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs
index a254d2be9..e48551425 100644
--- a/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs
+++ b/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs
@@ -1,17 +1,18 @@
-using System.Threading.Tasks;
+using System;
+using System.Threading.Tasks;
namespace MediaBrowser.Common.ScheduledTasks
{
/// <summary>
/// Class StartupTaskTrigger
/// </summary>
- public class StartupTrigger : BaseTaskTrigger
+ public class StartupTrigger : ITaskTrigger
{
/// <summary>
/// Stars waiting for the trigger action
/// </summary>
/// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
- protected internal async override void Start(bool isApplicationStartup)
+ public async void Start(bool isApplicationStartup)
{
if (isApplicationStartup)
{
@@ -24,8 +25,24 @@ namespace MediaBrowser.Common.ScheduledTasks
/// <summary>
/// Stops waiting for the trigger action
/// </summary>
- protected internal override void Stop()
+ public void Stop()
{
}
+
+ /// <summary>
+ /// Occurs when [triggered].
+ /// </summary>
+ public event EventHandler<EventArgs> Triggered;
+
+ /// <summary>
+ /// Called when [triggered].
+ /// </summary>
+ private void OnTriggered()
+ {
+ if (Triggered != null)
+ {
+ Triggered(this, EventArgs.Empty);
+ }
+ }
}
}
diff --git a/MediaBrowser.Common/ScheduledTasks/SystemEventTrigger.cs b/MediaBrowser.Common/ScheduledTasks/SystemEventTrigger.cs
index 45d1fae8e..751da0ca5 100644
--- a/MediaBrowser.Common/ScheduledTasks/SystemEventTrigger.cs
+++ b/MediaBrowser.Common/ScheduledTasks/SystemEventTrigger.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Model.Tasks;
using Microsoft.Win32;
+using System;
using System.Threading.Tasks;
namespace MediaBrowser.Common.ScheduledTasks
@@ -7,7 +8,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// <summary>
/// Class SystemEventTrigger
/// </summary>
- public class SystemEventTrigger : BaseTaskTrigger
+ public class SystemEventTrigger : ITaskTrigger
{
/// <summary>
/// Gets or sets the system event.
@@ -19,7 +20,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// Stars waiting for the trigger action
/// </summary>
/// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
- protected internal override void Start(bool isApplicationStartup)
+ public void Start(bool isApplicationStartup)
{
switch (SystemEvent)
{
@@ -32,7 +33,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// <summary>
/// Stops waiting for the trigger action
/// </summary>
- protected internal override void Stop()
+ public void Stop()
{
SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
}
@@ -52,5 +53,21 @@ namespace MediaBrowser.Common.ScheduledTasks
OnTriggered();
}
}
+
+ /// <summary>
+ /// Occurs when [triggered].
+ /// </summary>
+ public event EventHandler<EventArgs> Triggered;
+
+ /// <summary>
+ /// Called when [triggered].
+ /// </summary>
+ private void OnTriggered()
+ {
+ if (Triggered != null)
+ {
+ Triggered(this, EventArgs.Empty);
+ }
+ }
}
}
diff --git a/MediaBrowser.Common/ScheduledTasks/TaskManager.cs b/MediaBrowser.Common/ScheduledTasks/TaskManager.cs
deleted file mode 100644
index 946c42d2e..000000000
--- a/MediaBrowser.Common/ScheduledTasks/TaskManager.cs
+++ /dev/null
@@ -1,159 +0,0 @@
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Tasks;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace MediaBrowser.Common.ScheduledTasks
-{
- /// <summary>
- /// Class TaskManager
- /// </summary>
- internal class TaskManager : ITaskManager
- {
- /// <summary>
- /// Gets the list of Scheduled Tasks
- /// </summary>
- /// <value>The scheduled tasks.</value>
- public IScheduledTask[] ScheduledTasks { get; private set; }
-
- /// <summary>
- /// The _task queue
- /// </summary>
- private readonly List<Type> _taskQueue = new List<Type>();
-
- /// <summary>
- /// The _logger
- /// </summary>
- private readonly ILogger _logger;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="TaskManager" /> class.
- /// </summary>
- /// <param name="logger">The logger.</param>
- public TaskManager(ILogger logger)
- {
- if (logger == null)
- {
- throw new ArgumentException("logger");
- }
-
- _logger = logger;
-
- ScheduledTasks = new IScheduledTask[] {};
- }
-
- /// <summary>
- /// Cancels if running and queue.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public void CancelIfRunningAndQueue<T>()
- where T : IScheduledTask
- {
- ScheduledTasks.OfType<T>().First().CancelIfRunning();
- QueueScheduledTask<T>();
- }
-
- /// <summary>
- /// Queues the scheduled task.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public void QueueScheduledTask<T>()
- where T : IScheduledTask
- {
- var scheduledTask = ScheduledTasks.OfType<T>().First();
-
- QueueScheduledTask(scheduledTask);
- }
-
- /// <summary>
- /// Queues the scheduled task.
- /// </summary>
- /// <param name="task">The task.</param>
- public void QueueScheduledTask(IScheduledTask task)
- {
- var type = task.GetType();
-
- var scheduledTask = ScheduledTasks.First(t => t.GetType() == type);
-
- lock (_taskQueue)
- {
- // If it's idle just execute immediately
- if (scheduledTask.State == TaskState.Idle)
- {
- scheduledTask.Execute();
- return;
- }
-
- if (!_taskQueue.Contains(type))
- {
- _logger.Info("Queueing task {0}", type.Name);
- _taskQueue.Add(type);
- }
- else
- {
- _logger.Info("Task already queued: {0}", type.Name);
- }
- }
- }
-
- /// <summary>
- /// Called when [task completed].
- /// </summary>
- /// <param name="task">The task.</param>
- public void OnTaskCompleted(IScheduledTask task)
- {
- // Execute queued tasks
- lock (_taskQueue)
- {
- var copy = _taskQueue.ToList();
-
- foreach (var type in copy)
- {
- var scheduledTask = ScheduledTasks.First(t => t.GetType() == type);
-
- if (scheduledTask.State == TaskState.Idle)
- {
- scheduledTask.Execute();
-
- _taskQueue.Remove(type);
- }
- }
- }
- }
-
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources.
- /// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected virtual void Dispose(bool dispose)
- {
- foreach (var task in ScheduledTasks)
- {
- task.Dispose();
- }
- }
-
- /// <summary>
- /// Adds the tasks.
- /// </summary>
- /// <param name="tasks">The tasks.</param>
- public void AddTasks(IEnumerable<IScheduledTask> tasks)
- {
- var myTasks = ScheduledTasks.ToList();
-
- myTasks.AddRange(tasks);
-
- ScheduledTasks = myTasks.ToArray();
- }
- }
-}
diff --git a/MediaBrowser.Common/ScheduledTasks/WeeklyTrigger.cs b/MediaBrowser.Common/ScheduledTasks/WeeklyTrigger.cs
index afeacc2b3..cfb3f1fab 100644
--- a/MediaBrowser.Common/ScheduledTasks/WeeklyTrigger.cs
+++ b/MediaBrowser.Common/ScheduledTasks/WeeklyTrigger.cs
@@ -6,7 +6,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// <summary>
/// Represents a task trigger that fires on a weekly basis
/// </summary>
- public class WeeklyTrigger : BaseTaskTrigger
+ public class WeeklyTrigger : ITaskTrigger
{
/// <summary>
/// Get the time of day to trigger the task to run
@@ -30,7 +30,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// Stars waiting for the trigger action
/// </summary>
/// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
- protected internal override void Start(bool isApplicationStartup)
+ public void Start(bool isApplicationStartup)
{
DisposeTimer();
@@ -69,33 +69,35 @@ namespace MediaBrowser.Common.ScheduledTasks
/// <summary>
/// Stops waiting for the trigger action
/// </summary>
- protected internal override void Stop()
+ public void Stop()
{
DisposeTimer();
}
/// <summary>
- /// Disposes this instance.
+ /// Disposes the timer.
/// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected override void Dispose(bool dispose)
+ private void DisposeTimer()
{
- if (dispose)
+ if (Timer != null)
{
- DisposeTimer();
+ Timer.Dispose();
}
-
- base.Dispose(dispose);
}
/// <summary>
- /// Disposes the timer.
+ /// Occurs when [triggered].
/// </summary>
- private void DisposeTimer()
+ public event EventHandler<EventArgs> Triggered;
+
+ /// <summary>
+ /// Called when [triggered].
+ /// </summary>
+ private void OnTriggered()
{
- if (Timer != null)
+ if (Triggered != null)
{
- Timer.Dispose();
+ Triggered(this, EventArgs.Empty);
}
}
}
diff --git a/MediaBrowser.Common/packages.config b/MediaBrowser.Common/packages.config
index 0ebaf6297..ea25110aa 100644
--- a/MediaBrowser.Common/packages.config
+++ b/MediaBrowser.Common/packages.config
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="protobuf-net" version="2.0.0.621" targetFramework="net45" />
<package id="ServiceStack" version="3.9.37" targetFramework="net45" />
<package id="ServiceStack.Common" version="3.9.37" targetFramework="net45" />
<package id="ServiceStack.OrmLite.SqlServer" version="3.9.37" targetFramework="net45" />
diff --git a/MediaBrowser.Controller/Drawing/ImageManager.cs b/MediaBrowser.Controller/Drawing/ImageManager.cs
index a0ba9d550..766d56115 100644
--- a/MediaBrowser.Controller/Drawing/ImageManager.cs
+++ b/MediaBrowser.Controller/Drawing/ImageManager.cs
@@ -1,12 +1,12 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Kernel;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -22,7 +22,7 @@ namespace MediaBrowser.Controller.Drawing
/// <summary>
/// Class ImageManager
/// </summary>
- public class ImageManager : BaseManager<Kernel>
+ public class ImageManager : IDisposable
{
/// <summary>
/// Gets the image size cache.
@@ -58,19 +58,31 @@ namespace MediaBrowser.Controller.Drawing
private readonly ILogger _logger;
/// <summary>
+ /// The _protobuf serializer
+ /// </summary>
+ private readonly IProtobufSerializer _protobufSerializer;
+
+ /// <summary>
+ /// The _kernel
+ /// </summary>
+ private readonly Kernel _kernel;
+
+ /// <summary>
/// Initializes a new instance of the <see cref="ImageManager" /> class.
/// </summary>
/// <param name="kernel">The kernel.</param>
+ /// <param name="protobufSerializer">The protobuf serializer.</param>
/// <param name="logger">The logger.</param>
- public ImageManager(Kernel kernel, ILogger logger)
- : base(kernel)
+ public ImageManager(Kernel kernel, IProtobufSerializer protobufSerializer, ILogger logger)
{
+ _protobufSerializer = protobufSerializer;
_logger = logger;
+ _kernel = kernel;
- ImageSizeCache = new FileSystemRepository(Path.Combine(Kernel.ApplicationPaths.ImageCachePath, "image-sizes"));
- ResizedImageCache = new FileSystemRepository(Path.Combine(Kernel.ApplicationPaths.ImageCachePath, "resized-images"));
- CroppedImageCache = new FileSystemRepository(Path.Combine(Kernel.ApplicationPaths.ImageCachePath, "cropped-images"));
- EnhancedImageCache = new FileSystemRepository(Path.Combine(Kernel.ApplicationPaths.ImageCachePath, "enhanced-images"));
+ ImageSizeCache = new FileSystemRepository(Path.Combine(_kernel.ApplicationPaths.ImageCachePath, "image-sizes"));
+ ResizedImageCache = new FileSystemRepository(Path.Combine(_kernel.ApplicationPaths.ImageCachePath, "resized-images"));
+ CroppedImageCache = new FileSystemRepository(Path.Combine(_kernel.ApplicationPaths.ImageCachePath, "cropped-images"));
+ EnhancedImageCache = new FileSystemRepository(Path.Combine(_kernel.ApplicationPaths.ImageCachePath, "enhanced-images"));
}
/// <summary>
@@ -276,7 +288,7 @@ namespace MediaBrowser.Controller.Drawing
try
{
- var result = Kernel.ProtobufSerializer.DeserializeFromFile<int[]>(fullCachePath);
+ var result = _protobufSerializer.DeserializeFromFile<int[]>(fullCachePath);
return new ImageSize { Width = result[0], Height = result[1] };
}
@@ -305,7 +317,7 @@ namespace MediaBrowser.Controller.Drawing
{
var output = new[] { width, height };
- Kernel.ProtobufSerializer.SerializeToFile(output, cachePath);
+ _protobufSerializer.SerializeToFile(output, cachePath);
}
/// <summary>
@@ -472,7 +484,7 @@ namespace MediaBrowser.Controller.Drawing
throw new ArgumentNullException("item");
}
- var supportedEnhancers = Kernel.ImageEnhancers.Where(i => i.Supports(item, imageType)).ToList();
+ var supportedEnhancers = _kernel.ImageEnhancers.Where(i => i.Supports(item, imageType)).ToList();
// No enhancement - don't cache
if (supportedEnhancers.Count == 0)
@@ -526,7 +538,7 @@ namespace MediaBrowser.Controller.Drawing
var dateModified = GetImageDateModified(item, imagePath);
- var supportedEnhancers = Kernel.ImageEnhancers.Where(i => i.Supports(item, imageType));
+ var supportedEnhancers = _kernel.ImageEnhancers.Where(i => i.Supports(item, imageType));
return GetImageCacheTag(imagePath, dateModified, supportedEnhancers, item, imageType);
}
@@ -600,11 +612,16 @@ namespace MediaBrowser.Controller.Drawing
return result;
}
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected override void Dispose(bool dispose)
+ protected void Dispose(bool dispose)
{
if (dispose)
{
@@ -613,8 +630,6 @@ namespace MediaBrowser.Controller.Drawing
CroppedImageCache.Dispose();
EnhancedImageCache.Dispose();
}
-
- base.Dispose(dispose);
}
}
}
diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs
index 426e7f18e..5abd3e5a8 100644
--- a/MediaBrowser.Controller/Entities/User.cs
+++ b/MediaBrowser.Controller/Entities/User.cs
@@ -1,15 +1,13 @@
using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Serialization;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Tasks;
using System;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Controller.Entities
{
@@ -170,7 +168,7 @@ namespace MediaBrowser.Controller.Entities
get
{
// Lazy load
- LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationInitialized, ref _configurationSyncLock, () => XmlSerializer.GetXmlConfiguration<UserConfiguration>(ConfigurationFilePath, Logger));
+ LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationInitialized, ref _configurationSyncLock, () => (UserConfiguration)Kernel.Instance.GetXmlConfiguration(typeof(UserConfiguration), ConfigurationFilePath));
return _configuration;
}
private set
@@ -338,9 +336,9 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Saves the current configuration to the file system
/// </summary>
- public void SaveConfiguration()
+ public void SaveConfiguration(IXmlSerializer serializer)
{
- XmlSerializer.SerializeToFile(Configuration, ConfigurationFilePath);
+ serializer.SerializeToFile(Configuration, ConfigurationFilePath);
}
/// <summary>
@@ -376,8 +374,9 @@ namespace MediaBrowser.Controller.Entities
/// Updates the configuration.
/// </summary>
/// <param name="config">The config.</param>
+ /// <param name="serializer">The serializer.</param>
/// <exception cref="System.ArgumentNullException">config</exception>
- public void UpdateConfiguration(UserConfiguration config)
+ public void UpdateConfiguration(UserConfiguration config, IXmlSerializer serializer)
{
if (config == null)
{
@@ -387,7 +386,7 @@ namespace MediaBrowser.Controller.Entities
var customLibraryChanged = config.UseCustomLibrary != Configuration.UseCustomLibrary;
Configuration = config;
- SaveConfiguration();
+ SaveConfiguration(serializer);
// Force these to be lazy loaded again
if (customLibraryChanged)
diff --git a/MediaBrowser.Controller/IServerApplicationPaths.cs b/MediaBrowser.Controller/IServerApplicationPaths.cs
new file mode 100644
index 000000000..b5fcdef28
--- /dev/null
+++ b/MediaBrowser.Controller/IServerApplicationPaths.cs
@@ -0,0 +1,85 @@
+using MediaBrowser.Common.Kernel;
+
+namespace MediaBrowser.Controller
+{
+ public interface IServerApplicationPaths : IApplicationPaths
+ {
+ /// <summary>
+ /// Gets the path to the base root media directory
+ /// </summary>
+ /// <value>The root folder path.</value>
+ string RootFolderPath { get; }
+
+ /// <summary>
+ /// Gets the path to the default user view directory. Used if no specific user view is defined.
+ /// </summary>
+ /// <value>The default user views path.</value>
+ string DefaultUserViewsPath { get; }
+
+ /// <summary>
+ /// Gets the path to localization data.
+ /// </summary>
+ /// <value>The localization path.</value>
+ string LocalizationPath { get; }
+
+ /// <summary>
+ /// Gets the path to the Images By Name directory
+ /// </summary>
+ /// <value>The images by name path.</value>
+ string ImagesByNamePath { get; }
+
+ /// <summary>
+ /// Gets the path to the People directory
+ /// </summary>
+ /// <value>The people path.</value>
+ string PeoplePath { get; }
+
+ /// <summary>
+ /// Gets the path to the Genre directory
+ /// </summary>
+ /// <value>The genre path.</value>
+ string GenrePath { get; }
+
+ /// <summary>
+ /// Gets the path to the Studio directory
+ /// </summary>
+ /// <value>The studio path.</value>
+ string StudioPath { get; }
+
+ /// <summary>
+ /// Gets the path to the Year directory
+ /// </summary>
+ /// <value>The year path.</value>
+ string YearPath { get; }
+
+ /// <summary>
+ /// Gets the path to the General IBN directory
+ /// </summary>
+ /// <value>The general path.</value>
+ string GeneralPath { get; }
+
+ /// <summary>
+ /// Gets the path to the Ratings IBN directory
+ /// </summary>
+ /// <value>The ratings path.</value>
+ string RatingsPath { get; }
+
+ /// <summary>
+ /// Gets the path to the user configuration directory
+ /// </summary>
+ /// <value>The user configuration directory path.</value>
+ string UserConfigurationDirectoryPath { get; }
+
+ /// <summary>
+ /// Gets the FF MPEG stream cache path.
+ /// </summary>
+ /// <value>The FF MPEG stream cache path.</value>
+ string FFMpegStreamCachePath { get; }
+
+ /// <summary>
+ /// Gets the folder path to tools
+ /// </summary>
+ /// <value>The media tools path.</value>
+ string MediaToolsPath { get; }
+ }
+} \ No newline at end of file
diff --git a/MediaBrowser.Controller/Kernel.cs b/MediaBrowser.Controller/Kernel.cs
index 5ee590bde..d879b888b 100644
--- a/MediaBrowser.Controller/Kernel.cs
+++ b/MediaBrowser.Controller/Kernel.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Common.Kernel;
using MediaBrowser.Common.Plugins;
+using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.IO;
@@ -16,6 +17,7 @@ using MediaBrowser.Controller.Updates;
using MediaBrowser.Controller.Weather;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.System;
using System;
using System.Collections.Generic;
@@ -28,7 +30,7 @@ namespace MediaBrowser.Controller
/// <summary>
/// Class Kernel
/// </summary>
- public class Kernel : BaseKernel<ServerConfiguration, ServerApplicationPaths>
+ public class Kernel : BaseKernel<ServerConfiguration, IServerApplicationPaths>
{
/// <summary>
/// The MB admin URL
@@ -291,17 +293,24 @@ namespace MediaBrowser.Controller
get { return 7359; }
}
+ private readonly ITaskManager _taskManager;
+
/// <summary>
/// Creates a kernel based on a Data path, which is akin to our current programdata path
/// </summary>
/// <param name="appHost">The app host.</param>
+ /// <param name="appPaths">The app paths.</param>
+ /// <param name="xmlSerializer">The XML serializer.</param>
+ /// <param name="taskManager">The task manager.</param>
/// <param name="logger">The logger.</param>
/// <exception cref="System.ArgumentNullException">isoManager</exception>
- public Kernel(IApplicationHost appHost, ILogger logger)
- : base(appHost, logger)
+ public Kernel(IApplicationHost appHost, IServerApplicationPaths appPaths, IXmlSerializer xmlSerializer, ITaskManager taskManager, ILogger logger)
+ : base(appHost, appPaths, xmlSerializer, logger)
{
Instance = this;
+ _taskManager = taskManager;
+
// For now there's no real way to inject this properly
BaseItem.Logger = logger;
Ratings.Logger = logger;
@@ -311,20 +320,9 @@ namespace MediaBrowser.Controller
}
/// <summary>
- /// Composes the exported values.
- /// </summary>
- protected override void RegisterExportedValues()
- {
- ApplicationHost.RegisterSingleInstance(this);
-
- base.RegisterExportedValues();
- }
-
- /// <summary>
/// Composes the parts with ioc container.
/// </summary>
- /// <param name="allTypes">All types.</param>
- protected override void FindParts(Type[] allTypes)
+ protected override void FindParts()
{
InstallationManager = (InstallationManager)ApplicationHost.CreateInstance(typeof(InstallationManager));
FFMpegManager = (FFMpegManager)ApplicationHost.CreateInstance(typeof(FFMpegManager));
@@ -335,21 +333,21 @@ namespace MediaBrowser.Controller
UserDataManager = (UserDataManager)ApplicationHost.CreateInstance(typeof(UserDataManager));
PluginSecurityManager = (PluginSecurityManager)ApplicationHost.CreateInstance(typeof(PluginSecurityManager));
- base.FindParts(allTypes);
-
- EntityResolutionIgnoreRules = GetExports<IResolutionIgnoreRule>(allTypes);
- UserDataRepositories = GetExports<IUserDataRepository>(allTypes);
- UserRepositories = GetExports<IUserRepository>(allTypes);
- DisplayPreferencesRepositories = GetExports<IDisplayPreferencesRepository>(allTypes);
- ItemRepositories = GetExports<IItemRepository>(allTypes);
- WeatherProviders = GetExports<IWeatherProvider>(allTypes);
- IntroProviders = GetExports<IIntroProvider>(allTypes);
- PluginConfigurationPages = GetExports<IPluginConfigurationPage>(allTypes);
- ImageEnhancers = GetExports<IImageEnhancer>(allTypes).OrderBy(e => e.Priority).ToArray();
- PluginFolderCreators = GetExports<IVirtualFolderCreator>(allTypes);
- StringFiles = GetExports<LocalizedStringData>(allTypes);
- EntityResolvers = GetExports<IBaseItemResolver>(allTypes).OrderBy(e => e.Priority).ToArray();
- MetadataProviders = GetExports<BaseMetadataProvider>(allTypes).OrderBy(e => e.Priority).ToArray();
+ base.FindParts();
+
+ EntityResolutionIgnoreRules = ApplicationHost.GetExports<IResolutionIgnoreRule>();
+ UserDataRepositories = ApplicationHost.GetExports<IUserDataRepository>();
+ UserRepositories = ApplicationHost.GetExports<IUserRepository>();
+ DisplayPreferencesRepositories = ApplicationHost.GetExports<IDisplayPreferencesRepository>();
+ ItemRepositories = ApplicationHost.GetExports<IItemRepository>();
+ WeatherProviders = ApplicationHost.GetExports<IWeatherProvider>();
+ IntroProviders = ApplicationHost.GetExports<IIntroProvider>();
+ PluginConfigurationPages = ApplicationHost.GetExports<IPluginConfigurationPage>();
+ ImageEnhancers = ApplicationHost.GetExports<IImageEnhancer>().OrderBy(e => e.Priority).ToArray();
+ PluginFolderCreators = ApplicationHost.GetExports<IVirtualFolderCreator>();
+ StringFiles = ApplicationHost.GetExports<LocalizedStringData>();
+ EntityResolvers = ApplicationHost.GetExports<IBaseItemResolver>().OrderBy(e => e.Priority).ToArray();
+ MetadataProviders = ApplicationHost.GetExports<BaseMetadataProvider>().OrderBy(e => e.Priority).ToArray();
}
/// <summary>
@@ -471,7 +469,7 @@ namespace MediaBrowser.Controller
{
DisposeFileSystemManager();
- FileSystemManager = new FileSystemManager(this, Logger, TaskManager);
+ FileSystemManager = new FileSystemManager(this, Logger, _taskManager);
FileSystemManager.StartWatchers();
}
@@ -570,11 +568,11 @@ namespace MediaBrowser.Controller
ProviderManager.ValidateCurrentlyRunningProviders();
// Any number of configuration settings could change the way the library is refreshed, so do that now
- TaskManager.CancelIfRunningAndQueue<RefreshMediaLibraryTask>();
+ _taskManager.CancelIfRunningAndQueue<RefreshMediaLibraryTask>();
if (refreshPeopleAfterUpdate)
{
- TaskManager.CancelIfRunningAndQueue<PeopleValidationTask>();
+ _taskManager.CancelIfRunningAndQueue<PeopleValidationTask>();
}
});
}
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 35540020e..1e901055e 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -110,6 +110,7 @@
<Compile Include="IO\FileSystem.cs" />
<Compile Include="IO\FileSystemManager.cs" />
<Compile Include="IO\NativeMethods.cs" />
+ <Compile Include="IServerApplicationPaths.cs" />
<Compile Include="Library\ChildrenChangedEventArgs.cs" />
<Compile Include="Library\DtoBuilder.cs" />
<Compile Include="Library\Profiler.cs" />
@@ -183,7 +184,6 @@
<Compile Include="ScheduledTasks\PeopleValidationTask.cs" />
<Compile Include="ScheduledTasks\PluginUpdateTask.cs" />
<Compile Include="ScheduledTasks\RefreshMediaLibraryTask.cs" />
- <Compile Include="ServerApplicationPaths.cs" />
<Compile Include="Library\ItemResolveArgs.cs" />
<Compile Include="IO\DirectoryWatchers.cs" />
<Compile Include="IO\FileData.cs" />
diff --git a/MediaBrowser.Controller/MediaInfo/FFMpegManager.cs b/MediaBrowser.Controller/MediaInfo/FFMpegManager.cs
index 9c9b0e9f2..0f535208b 100644
--- a/MediaBrowser.Controller/MediaInfo/FFMpegManager.cs
+++ b/MediaBrowser.Controller/MediaInfo/FFMpegManager.cs
@@ -1,12 +1,10 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Serialization;
+using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@@ -23,7 +21,7 @@ namespace MediaBrowser.Controller.MediaInfo
/// <summary>
/// Class FFMpegManager
/// </summary>
- public class FFMpegManager : BaseManager<Kernel>
+ public class FFMpegManager : IDisposable
{
/// <summary>
/// Gets or sets the video image cache.
@@ -47,30 +45,66 @@ namespace MediaBrowser.Controller.MediaInfo
/// Gets or sets the zip client.
/// </summary>
/// <value>The zip client.</value>
- private IZipClient ZipClient { get; set; }
+ private readonly IZipClient _zipClient;
/// <summary>
/// The _logger
/// </summary>
+ private readonly Kernel _kernel;
+
+ /// <summary>
+ /// The _logger
+ /// </summary>
private readonly ILogger _logger;
/// <summary>
+ /// Gets the json serializer.
+ /// </summary>
+ /// <value>The json serializer.</value>
+ private readonly IJsonSerializer _jsonSerializer;
+
+ /// <summary>
+ /// The _protobuf serializer
+ /// </summary>
+ private readonly IProtobufSerializer _protobufSerializer;
+
+ /// <summary>
/// Initializes a new instance of the <see cref="FFMpegManager" /> class.
/// </summary>
/// <param name="kernel">The kernel.</param>
/// <param name="zipClient">The zip client.</param>
+ /// <param name="jsonSerializer">The json serializer.</param>
+ /// <param name="protobufSerializer">The protobuf serializer.</param>
/// <param name="logger">The logger.</param>
/// <exception cref="System.ArgumentNullException">zipClient</exception>
- public FFMpegManager(Kernel kernel, IZipClient zipClient, ILogger logger)
- : base(kernel)
+ public FFMpegManager(Kernel kernel, IZipClient zipClient, IJsonSerializer jsonSerializer, IProtobufSerializer protobufSerializer, ILogger logger)
{
+ if (kernel == null)
+ {
+ throw new ArgumentNullException("kernel");
+ }
if (zipClient == null)
{
throw new ArgumentNullException("zipClient");
}
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
+ if (protobufSerializer == null)
+ {
+ throw new ArgumentNullException("protobufSerializer");
+ }
+ if (logger == null)
+ {
+ throw new ArgumentNullException("logger");
+ }
+ _kernel = kernel;
+ _zipClient = zipClient;
+ _jsonSerializer = jsonSerializer;
+ _protobufSerializer = protobufSerializer;
_logger = logger;
- ZipClient = zipClient;
// Not crazy about this but it's the only way to suppress ffmpeg crash dialog boxes
SetErrorMode(ErrorModes.SEM_FAILCRITICALERRORS | ErrorModes.SEM_NOALIGNMENTFAULTEXCEPT | ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX);
@@ -82,11 +116,16 @@ namespace MediaBrowser.Controller.MediaInfo
Task.Run(() => VersionedDirectoryPath = GetVersionedDirectoryPath());
}
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected override void Dispose(bool dispose)
+ protected void Dispose(bool dispose)
{
if (dispose)
{
@@ -95,8 +134,6 @@ namespace MediaBrowser.Controller.MediaInfo
AudioImageCache.Dispose();
VideoImageCache.Dispose();
}
-
- base.Dispose(dispose);
}
/// <summary>
@@ -186,7 +223,7 @@ namespace MediaBrowser.Controller.MediaInfo
{
if (_videoImagesDataPath == null)
{
- _videoImagesDataPath = Path.Combine(Kernel.ApplicationPaths.DataPath, "ffmpeg-video-images");
+ _videoImagesDataPath = Path.Combine(_kernel.ApplicationPaths.DataPath, "ffmpeg-video-images");
if (!Directory.Exists(_videoImagesDataPath))
{
@@ -212,7 +249,7 @@ namespace MediaBrowser.Controller.MediaInfo
{
if (_audioImagesDataPath == null)
{
- _audioImagesDataPath = Path.Combine(Kernel.ApplicationPaths.DataPath, "ffmpeg-audio-images");
+ _audioImagesDataPath = Path.Combine(_kernel.ApplicationPaths.DataPath, "ffmpeg-audio-images");
if (!Directory.Exists(_audioImagesDataPath))
{
@@ -238,7 +275,7 @@ namespace MediaBrowser.Controller.MediaInfo
{
if (_subtitleCachePath == null)
{
- _subtitleCachePath = Path.Combine(Kernel.ApplicationPaths.CachePath, "ffmpeg-subtitles");
+ _subtitleCachePath = Path.Combine(_kernel.ApplicationPaths.CachePath, "ffmpeg-subtitles");
if (!Directory.Exists(_subtitleCachePath))
{
@@ -265,7 +302,7 @@ namespace MediaBrowser.Controller.MediaInfo
var filename = resource.Substring(resource.IndexOf(prefix, StringComparison.OrdinalIgnoreCase) + prefix.Length);
- var versionedDirectoryPath = Path.Combine(Kernel.ApplicationPaths.MediaToolsPath, Path.GetFileNameWithoutExtension(filename));
+ var versionedDirectoryPath = Path.Combine(_kernel.ApplicationPaths.MediaToolsPath, Path.GetFileNameWithoutExtension(filename));
if (!Directory.Exists(versionedDirectoryPath))
{
@@ -287,7 +324,7 @@ namespace MediaBrowser.Controller.MediaInfo
{
using (var resourceStream = assembly.GetManifestResourceStream(zipFileResourcePath))
{
- ZipClient.ExtractAll(resourceStream, targetPath, false);
+ _zipClient.ExtractAll(resourceStream, targetPath, false);
}
}
@@ -353,7 +390,7 @@ namespace MediaBrowser.Controller.MediaInfo
// Avoid File.Exists by just trying to deserialize
try
{
- return Task.FromResult(Kernel.ProtobufSerializer.DeserializeFromFile<FFProbeResult>(cacheFilePath));
+ return Task.FromResult(_protobufSerializer.DeserializeFromFile<FFProbeResult>(cacheFilePath));
}
catch (FileNotFoundException)
{
@@ -428,7 +465,7 @@ namespace MediaBrowser.Controller.MediaInfo
process.BeginErrorReadLine();
}
- result = JsonSerializer.DeserializeFromStream<FFProbeResult>(process.StandardOutput.BaseStream);
+ result = _jsonSerializer.DeserializeFromStream<FFProbeResult>(process.StandardOutput.BaseStream);
if (extractChapters)
{
@@ -470,7 +507,7 @@ namespace MediaBrowser.Controller.MediaInfo
AddChapters(result, standardError);
}
- Kernel.ProtobufSerializer.SerializeToFile(result, cacheFile);
+ _protobufSerializer.SerializeToFile(result, cacheFile);
return result;
}
@@ -595,7 +632,7 @@ namespace MediaBrowser.Controller.MediaInfo
if (saveItem && changesMade)
{
- await Kernel.ItemRepository.SaveItem(video, CancellationToken.None).ConfigureAwait(false);
+ await _kernel.ItemRepository.SaveItem(video, CancellationToken.None).ConfigureAwait(false);
}
}
diff --git a/MediaBrowser.Controller/Providers/MediaInfo/FFProbeVideoInfoProvider.cs b/MediaBrowser.Controller/Providers/MediaInfo/FFProbeVideoInfoProvider.cs
index 443d28b67..8905656ef 100644
--- a/MediaBrowser.Controller/Providers/MediaInfo/FFProbeVideoInfoProvider.cs
+++ b/MediaBrowser.Controller/Providers/MediaInfo/FFProbeVideoInfoProvider.cs
@@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.MediaInfo;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.MediaInfo;
+using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
using System.IO;
@@ -28,29 +29,44 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
/// Gets or sets the bluray examiner.
/// </summary>
/// <value>The bluray examiner.</value>
- private IBlurayExaminer BlurayExaminer { get; set; }
+ private readonly IBlurayExaminer _blurayExaminer;
- /// <summary>
+ /// <summary>
/// The _iso manager
/// </summary>
private readonly IIsoManager _isoManager;
/// <summary>
+ /// The _protobuf serializer
+ /// </summary>
+ private readonly IProtobufSerializer _protobufSerializer;
+
+ /// <summary>
/// Initializes a new instance of the <see cref="FFProbeVideoInfoProvider" /> class.
/// </summary>
/// <param name="isoManager">The iso manager.</param>
/// <param name="blurayExaminer">The bluray examiner.</param>
+ /// <param name="protobufSerializer">The protobuf serializer.</param>
/// <exception cref="System.ArgumentNullException">blurayExaminer</exception>
- public FFProbeVideoInfoProvider(IIsoManager isoManager, IBlurayExaminer blurayExaminer)
+ public FFProbeVideoInfoProvider(IIsoManager isoManager, IBlurayExaminer blurayExaminer, IProtobufSerializer protobufSerializer)
: base()
{
+ if (isoManager == null)
+ {
+ throw new ArgumentNullException("isoManager");
+ }
if (blurayExaminer == null)
{
throw new ArgumentNullException("blurayExaminer");
}
+ if (protobufSerializer == null)
+ {
+ throw new ArgumentNullException("protobufSerializer");
+ }
- BlurayExaminer = blurayExaminer;
+ _blurayExaminer = blurayExaminer;
_isoManager = isoManager;
+ _protobufSerializer = protobufSerializer;
BdInfoCache = new FileSystemRepository(Path.Combine(Kernel.Instance.ApplicationPaths.CachePath, "bdinfo"));
}
@@ -315,13 +331,13 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
try
{
- result = Kernel.Instance.ProtobufSerializer.DeserializeFromFile<BlurayDiscInfo>(cacheFile);
+ result = _protobufSerializer.DeserializeFromFile<BlurayDiscInfo>(cacheFile);
}
catch (FileNotFoundException)
{
result = GetBDInfo(inputPath);
- Kernel.Instance.ProtobufSerializer.SerializeToFile(result, cacheFile);
+ _protobufSerializer.SerializeToFile(result, cacheFile);
}
cancellationToken.ThrowIfCancellationRequested();
@@ -400,7 +416,7 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
/// <returns>VideoStream.</returns>
private BlurayDiscInfo GetBDInfo(string path)
{
- return BlurayExaminer.GetDiscInfo(path);
+ return _blurayExaminer.GetDiscInfo(path);
}
/// <summary>
diff --git a/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs
index 72f8a3fc7..bc261de6d 100644
--- a/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs
+++ b/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs
@@ -1,5 +1,4 @@
using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.Serialization;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Model.Entities;
@@ -15,6 +14,7 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Controller.Providers.Movies
{
@@ -31,6 +31,27 @@ namespace MediaBrowser.Controller.Providers.Movies
public class MovieDbProvider : BaseMetadataProvider
{
/// <summary>
+ /// Gets the json serializer.
+ /// </summary>
+ /// <value>The json serializer.</value>
+ protected IJsonSerializer JsonSerializer { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MovieDbProvider" /> class.
+ /// </summary>
+ /// <param name="jsonSerializer">The json serializer.</param>
+ /// <exception cref="System.ArgumentNullException">jsonSerializer</exception>
+ public MovieDbProvider(IJsonSerializer jsonSerializer)
+ : base()
+ {
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
+ JsonSerializer = jsonSerializer;
+ }
+
+ /// <summary>
/// Gets the priority.
/// </summary>
/// <value>The priority.</value>
@@ -93,7 +114,7 @@ namespace MediaBrowser.Controller.Providers.Movies
{
get
{
- LazyInitializer.EnsureInitialized(ref _tmdbSettingsTask, ref _tmdbSettingsTaskInitialized, ref _tmdbSettingsTaskSyncLock, GetTmdbSettings);
+ LazyInitializer.EnsureInitialized(ref _tmdbSettingsTask, ref _tmdbSettingsTaskInitialized, ref _tmdbSettingsTaskSyncLock, () => GetTmdbSettings(JsonSerializer));
return _tmdbSettingsTask;
}
}
@@ -102,13 +123,13 @@ namespace MediaBrowser.Controller.Providers.Movies
/// Gets the TMDB settings.
/// </summary>
/// <returns>Task{TmdbSettingsResult}.</returns>
- private static async Task<TmdbSettingsResult> GetTmdbSettings()
+ private static async Task<TmdbSettingsResult> GetTmdbSettings(IJsonSerializer jsonSerializer)
{
try
{
using (var json = await Kernel.Instance.HttpManager.Get(String.Format(TmdbConfigUrl, ApiKey), Kernel.Instance.ResourcePools.MovieDb, CancellationToken.None).ConfigureAwait(false))
{
- return JsonSerializer.DeserializeFromStream<TmdbSettingsResult>(json);
+ return jsonSerializer.DeserializeFromStream<TmdbSettingsResult>(json);
}
}
catch (HttpException e)
@@ -168,7 +189,7 @@ namespace MediaBrowser.Controller.Providers.Movies
{
//in addition to ours, we need to set the last refreshed time for the local data provider
//so it won't see the new files we download and process them all over again
- if (JsonProvider == null) JsonProvider = new MovieProviderFromJson();
+ if (JsonProvider == null) JsonProvider = new MovieProviderFromJson(JsonSerializer);
var data = item.ProviderData.GetValueOrDefault(JsonProvider.Id, new BaseProviderInfo { ProviderId = JsonProvider.Id });
data.LastRefreshed = value;
item.ProviderData[JsonProvider.Id] = data;
diff --git a/MediaBrowser.Controller/Providers/Movies/MovieProviderFromJson.cs b/MediaBrowser.Controller/Providers/Movies/MovieProviderFromJson.cs
index 45079ddda..5de17aab0 100644
--- a/MediaBrowser.Controller/Providers/Movies/MovieProviderFromJson.cs
+++ b/MediaBrowser.Controller/Providers/Movies/MovieProviderFromJson.cs
@@ -1,5 +1,5 @@
-using MediaBrowser.Common.Serialization;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Serialization;
using System;
using System.IO;
using System.Threading;
@@ -12,6 +12,10 @@ namespace MediaBrowser.Controller.Providers.Movies
/// </summary>
public class MovieProviderFromJson : MovieDbProvider
{
+ public MovieProviderFromJson(IJsonSerializer jsonSerializer) : base(jsonSerializer)
+ {
+ }
+
/// <summary>
/// Gets the priority.
/// </summary>
diff --git a/MediaBrowser.Controller/Providers/Movies/PersonProviderFromJson.cs b/MediaBrowser.Controller/Providers/Movies/PersonProviderFromJson.cs
index b4b4933e2..7517ec65c 100644
--- a/MediaBrowser.Controller/Providers/Movies/PersonProviderFromJson.cs
+++ b/MediaBrowser.Controller/Providers/Movies/PersonProviderFromJson.cs
@@ -1,5 +1,5 @@
-using MediaBrowser.Common.Serialization;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Serialization;
using System;
using System.IO;
using System.Threading;
@@ -12,6 +12,10 @@ namespace MediaBrowser.Controller.Providers.Movies
/// </summary>
class PersonProviderFromJson : TmdbPersonProvider
{
+ public PersonProviderFromJson(IJsonSerializer jsonSerializer) : base(jsonSerializer)
+ {
+ }
+
/// <summary>
/// Supportses the specified item.
/// </summary>
diff --git a/MediaBrowser.Controller/Providers/Movies/TmdbPersonProvider.cs b/MediaBrowser.Controller/Providers/Movies/TmdbPersonProvider.cs
index 7b5d62fb0..32013614c 100644
--- a/MediaBrowser.Controller/Providers/Movies/TmdbPersonProvider.cs
+++ b/MediaBrowser.Controller/Providers/Movies/TmdbPersonProvider.cs
@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Serialization;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Net;
using System;
@@ -10,6 +9,7 @@ using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Controller.Providers.Movies
{
@@ -24,6 +24,27 @@ namespace MediaBrowser.Controller.Providers.Movies
protected const string MetaFileName = "MBPerson.json";
/// <summary>
+ /// Gets the json serializer.
+ /// </summary>
+ /// <value>The json serializer.</value>
+ protected IJsonSerializer JsonSerializer { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MovieDbProvider" /> class.
+ /// </summary>
+ /// <param name="jsonSerializer">The json serializer.</param>
+ /// <exception cref="System.ArgumentNullException">jsonSerializer</exception>
+ public TmdbPersonProvider(IJsonSerializer jsonSerializer)
+ : base()
+ {
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
+ JsonSerializer = jsonSerializer;
+ }
+
+ /// <summary>
/// Supportses the specified item.
/// </summary>
/// <param name="item">The item.</param>
@@ -56,7 +77,7 @@ namespace MediaBrowser.Controller.Providers.Movies
protected override async Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
-
+
var person = (Person)item;
var tasks = new List<Task>();
@@ -169,7 +190,7 @@ namespace MediaBrowser.Controller.Providers.Movies
}
cancellationToken.ThrowIfCancellationRequested();
-
+
if (searchResult != null && searchResult.Biography != null)
{
ProcessInfo(person, searchResult);
diff --git a/MediaBrowser.Controller/ScheduledTasks/ChapterImagesTask.cs b/MediaBrowser.Controller/ScheduledTasks/ChapterImagesTask.cs
index 1a64bb853..536033719 100644
--- a/MediaBrowser.Controller/ScheduledTasks/ChapterImagesTask.cs
+++ b/MediaBrowser.Controller/ScheduledTasks/ChapterImagesTask.cs
@@ -28,9 +28,9 @@ namespace MediaBrowser.Controller.ScheduledTasks
/// Creates the triggers that define when the task will run
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- protected override IEnumerable<BaseTaskTrigger> GetDefaultTriggers()
+ public override IEnumerable<ITaskTrigger> GetDefaultTriggers()
{
- return new BaseTaskTrigger[]
+ return new ITaskTrigger[]
{
new DailyTrigger { TimeOfDay = TimeSpan.FromHours(4) }
};
diff --git a/MediaBrowser.Controller/ScheduledTasks/ImageCleanupTask.cs b/MediaBrowser.Controller/ScheduledTasks/ImageCleanupTask.cs
index 8dd0895c9..7e0094a67 100644
--- a/MediaBrowser.Controller/ScheduledTasks/ImageCleanupTask.cs
+++ b/MediaBrowser.Controller/ScheduledTasks/ImageCleanupTask.cs
@@ -20,7 +20,8 @@ namespace MediaBrowser.Controller.ScheduledTasks
/// Initializes a new instance of the <see cref="ImageCleanupTask" /> class.
/// </summary>
/// <param name="kernel">The kernel.</param>
- /// <param name="logger"></param>
+ /// <param name="taskManager">The task manager.</param>
+ /// <param name="logger">The logger.</param>
public ImageCleanupTask(Kernel kernel, ITaskManager taskManager, ILogger logger)
: base(kernel, taskManager, logger)
{
@@ -30,9 +31,9 @@ namespace MediaBrowser.Controller.ScheduledTasks
/// Creates the triggers that define when the task will run
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- protected override IEnumerable<BaseTaskTrigger> GetDefaultTriggers()
+ public override IEnumerable<ITaskTrigger> GetDefaultTriggers()
{
- return new BaseTaskTrigger[]
+ return new ITaskTrigger[]
{
new DailyTrigger { TimeOfDay = TimeSpan.FromHours(2) }
};
diff --git a/MediaBrowser.Controller/ScheduledTasks/PeopleValidationTask.cs b/MediaBrowser.Controller/ScheduledTasks/PeopleValidationTask.cs
index ee55ff2e9..595de684d 100644
--- a/MediaBrowser.Controller/ScheduledTasks/PeopleValidationTask.cs
+++ b/MediaBrowser.Controller/ScheduledTasks/PeopleValidationTask.cs
@@ -26,9 +26,9 @@ namespace MediaBrowser.Controller.ScheduledTasks
/// Creates the triggers that define when the task will run
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- protected override IEnumerable<BaseTaskTrigger> GetDefaultTriggers()
+ public override IEnumerable<ITaskTrigger> GetDefaultTriggers()
{
- return new BaseTaskTrigger[]
+ return new ITaskTrigger[]
{
new DailyTrigger { TimeOfDay = TimeSpan.FromHours(2) },
diff --git a/MediaBrowser.Controller/ScheduledTasks/PluginUpdateTask.cs b/MediaBrowser.Controller/ScheduledTasks/PluginUpdateTask.cs
index 854c3b82f..7a1007f1b 100644
--- a/MediaBrowser.Controller/ScheduledTasks/PluginUpdateTask.cs
+++ b/MediaBrowser.Controller/ScheduledTasks/PluginUpdateTask.cs
@@ -29,9 +29,9 @@ namespace MediaBrowser.Controller.ScheduledTasks
/// Creates the triggers that define when the task will run
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- protected override IEnumerable<BaseTaskTrigger> GetDefaultTriggers()
+ public override IEnumerable<ITaskTrigger> GetDefaultTriggers()
{
- return new BaseTaskTrigger[] {
+ return new ITaskTrigger[] {
// 1:30am
new DailyTrigger { TimeOfDay = TimeSpan.FromHours(1.5) },
diff --git a/MediaBrowser.Controller/ScheduledTasks/RefreshMediaLibraryTask.cs b/MediaBrowser.Controller/ScheduledTasks/RefreshMediaLibraryTask.cs
index 76e60f2ef..104b432f4 100644
--- a/MediaBrowser.Controller/ScheduledTasks/RefreshMediaLibraryTask.cs
+++ b/MediaBrowser.Controller/ScheduledTasks/RefreshMediaLibraryTask.cs
@@ -27,9 +27,9 @@ namespace MediaBrowser.Controller.ScheduledTasks
/// Gets the default triggers.
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- protected override IEnumerable<BaseTaskTrigger> GetDefaultTriggers()
+ public override IEnumerable<ITaskTrigger> GetDefaultTriggers()
{
- return new BaseTaskTrigger[] {
+ return new ITaskTrigger[] {
new StartupTrigger(),
diff --git a/MediaBrowser.Controller/Updates/InstallationManager.cs b/MediaBrowser.Controller/Updates/InstallationManager.cs
index bef5a6472..af544dd51 100644
--- a/MediaBrowser.Controller/Updates/InstallationManager.cs
+++ b/MediaBrowser.Controller/Updates/InstallationManager.cs
@@ -1,18 +1,17 @@
-using System.Security.Cryptography;
-using MediaBrowser.Common.Events;
-using MediaBrowser.Common.Kernel;
+using MediaBrowser.Common.Events;
using MediaBrowser.Common.Net;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.Progress;
-using MediaBrowser.Common.Serialization;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Updates;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
@@ -32,8 +31,8 @@ namespace MediaBrowser.Controller.Updates
/// <summary>
/// The completed installations
/// </summary>
- public readonly ConcurrentBag<InstallationInfo> CompletedInstallations = new ConcurrentBag<InstallationInfo>();
-
+ public readonly ConcurrentBag<InstallationInfo> CompletedInstallations = new ConcurrentBag<InstallationInfo>();
+
#region PluginUninstalled Event
/// <summary>
/// Occurs when [plugin uninstalled].
@@ -68,7 +67,7 @@ namespace MediaBrowser.Controller.Updates
_logger.Info("Plugin updated: {0} {1} {2}", newVersion.name, newVersion.version, newVersion.classification);
EventHelper.QueueEventIfNotNull(PluginUpdated, this, new GenericEventArgs<Tuple<IPlugin, PackageVersionInfo>> { Argument = new Tuple<IPlugin, PackageVersionInfo>(plugin, newVersion) }, _logger);
-
+
Kernel.NotifyPendingRestart();
}
#endregion
@@ -109,14 +108,21 @@ namespace MediaBrowser.Controller.Updates
private readonly INetworkManager _networkManager;
/// <summary>
+ /// Gets the json serializer.
+ /// </summary>
+ /// <value>The json serializer.</value>
+ protected IJsonSerializer JsonSerializer { get; private set; }
+
+ /// <summary>
/// Initializes a new instance of the <see cref="InstallationManager" /> class.
/// </summary>
/// <param name="kernel">The kernel.</param>
/// <param name="zipClient">The zip client.</param>
/// <param name="networkManager">The network manager.</param>
+ /// <param name="jsonSerializer"></param>
/// <param name="logger">The logger.</param>
/// <exception cref="System.ArgumentNullException">zipClient</exception>
- public InstallationManager(Kernel kernel, IZipClient zipClient, INetworkManager networkManager, ILogger logger)
+ public InstallationManager(Kernel kernel, IZipClient zipClient, INetworkManager networkManager, IJsonSerializer jsonSerializer, ILogger logger)
: base(kernel)
{
if (zipClient == null)
@@ -131,6 +137,12 @@ namespace MediaBrowser.Controller.Updates
{
throw new ArgumentNullException("logger");
}
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
+
+ JsonSerializer = jsonSerializer;
_networkManager = networkManager;
_logger = logger;
@@ -161,7 +173,7 @@ namespace MediaBrowser.Controller.Updates
package.versions = package.versions.Where(v => !string.IsNullOrWhiteSpace(v.sourceUrl))
.OrderByDescending(v => v.version).ToList();
}
-
+
if (packageType.HasValue)
{
packages = packages.Where(p => p.type == packageType.Value).ToList();
@@ -178,7 +190,7 @@ namespace MediaBrowser.Controller.Updates
// Remove packages with no versions
packages = packages.Where(p => p.versions.Any()).ToList();
-
+
return packages;
}
}
@@ -320,7 +332,7 @@ namespace MediaBrowser.Controller.Updates
var innerCancellationTokenSource = new CancellationTokenSource();
var tuple = new Tuple<InstallationInfo, CancellationTokenSource>(installationInfo, innerCancellationTokenSource);
-
+
// Add it to the in-progress list
lock (CurrentInstallations)
{
@@ -364,7 +376,7 @@ namespace MediaBrowser.Controller.Updates
_logger.Info("Package installation cancelled: {0} {1}", package.name, package.versionStr);
Kernel.TcpManager.SendWebSocketMessage("PackageInstallationCancelled", installationInfo);
-
+
throw;
}
catch
@@ -373,7 +385,7 @@ namespace MediaBrowser.Controller.Updates
{
CurrentInstallations.Remove(tuple);
}
-
+
Kernel.TcpManager.SendWebSocketMessage("PackageInstallationFailed", installationInfo);
throw;
@@ -421,7 +433,7 @@ namespace MediaBrowser.Controller.Updates
}
cancellationToken.ThrowIfCancellationRequested();
-
+
// Success - move it to the real target based on type
if (isArchive)
{
@@ -435,7 +447,7 @@ namespace MediaBrowser.Controller.Updates
throw;
}
- }
+ }
else
{
try
@@ -448,8 +460,8 @@ namespace MediaBrowser.Controller.Updates
_logger.ErrorException("Error attempting to move file from {0} to {1}", e, tempFile, target);
throw;
}
- }
-
+ }
+
// Set last update time if we were installed before
var plugin = Kernel.Plugins.FirstOrDefault(p => p.Name.Equals(package.name, StringComparison.OrdinalIgnoreCase));
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 372aefdc6..8e8f88c20 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -75,6 +75,9 @@
<Compile Include="Net\HttpException.cs" />
<Compile Include="Net\NetworkShare.cs" />
<Compile Include="Net\NetworkShareType.cs" />
+ <Compile Include="Serialization\IJsonSerializer.cs" />
+ <Compile Include="Serialization\IProtobufSerializer.cs" />
+ <Compile Include="Serialization\IXmlSerializer.cs" />
<Compile Include="Updates\CheckForUpdateResult.cs" />
<Compile Include="Updates\InstallationInfo.cs" />
<Compile Include="Updates\PackageType.cs" />
diff --git a/MediaBrowser.Model/Serialization/IJsonSerializer.cs b/MediaBrowser.Model/Serialization/IJsonSerializer.cs
new file mode 100644
index 000000000..056389d2e
--- /dev/null
+++ b/MediaBrowser.Model/Serialization/IJsonSerializer.cs
@@ -0,0 +1,103 @@
+using System;
+using System.IO;
+
+namespace MediaBrowser.Model.Serialization
+{
+ public interface IJsonSerializer
+ {
+ /// <summary>
+ /// Serializes to stream.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="obj">The obj.</param>
+ /// <param name="stream">The stream.</param>
+ /// <exception cref="System.ArgumentNullException">obj</exception>
+ void SerializeToStream<T>(T obj, Stream stream)
+ where T : class;
+
+ /// <summary>
+ /// Serializes to file.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="obj">The obj.</param>
+ /// <param name="file">The file.</param>
+ /// <exception cref="System.ArgumentNullException">obj</exception>
+ void SerializeToFile<T>(T obj, string file)
+ where T : class;
+
+ /// <summary>
+ /// Deserializes from file.
+ /// </summary>
+ /// <param name="type">The type.</param>
+ /// <param name="file">The file.</param>
+ /// <returns>System.Object.</returns>
+ /// <exception cref="System.ArgumentNullException">type</exception>
+ object DeserializeFromFile(Type type, string file);
+
+ /// <summary>
+ /// Deserializes from file.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="file">The file.</param>
+ /// <returns>``0.</returns>
+ /// <exception cref="System.ArgumentNullException">file</exception>
+ T DeserializeFromFile<T>(string file)
+ where T : class;
+
+ /// <summary>
+ /// Deserializes from stream.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="stream">The stream.</param>
+ /// <returns>``0.</returns>
+ /// <exception cref="System.ArgumentNullException">stream</exception>
+ T DeserializeFromStream<T>(Stream stream);
+
+ /// <summary>
+ /// Deserializes from string.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="text">The text.</param>
+ /// <returns>``0.</returns>
+ /// <exception cref="System.ArgumentNullException">text</exception>
+ T DeserializeFromString<T>(string text);
+
+ /// <summary>
+ /// Deserializes from stream.
+ /// </summary>
+ /// <param name="stream">The stream.</param>
+ /// <param name="type">The type.</param>
+ /// <returns>System.Object.</returns>
+ /// <exception cref="System.ArgumentNullException">stream</exception>
+ object DeserializeFromStream(Stream stream, Type type);
+
+ /// <summary>
+ /// Deserializes from string.
+ /// </summary>
+ /// <param name="json">The json.</param>
+ /// <param name="type">The type.</param>
+ /// <returns>System.Object.</returns>
+ /// <exception cref="System.ArgumentNullException">json</exception>
+ object DeserializeFromString(string json, Type type);
+
+ /// <summary>
+ /// Serializes to string.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="obj">The obj.</param>
+ /// <returns>System.String.</returns>
+ /// <exception cref="System.ArgumentNullException">obj</exception>
+ string SerializeToString<T>(T obj)
+ where T : class;
+
+ /// <summary>
+ /// Serializes to bytes.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="obj">The obj.</param>
+ /// <returns>System.Byte[][].</returns>
+ /// <exception cref="System.ArgumentNullException">obj</exception>
+ byte[] SerializeToBytes<T>(T obj)
+ where T : class;
+ }
+} \ No newline at end of file
diff --git a/MediaBrowser.Model/Serialization/IProtobufSerializer.cs b/MediaBrowser.Model/Serialization/IProtobufSerializer.cs
new file mode 100644
index 000000000..4c3ef6960
--- /dev/null
+++ b/MediaBrowser.Model/Serialization/IProtobufSerializer.cs
@@ -0,0 +1,63 @@
+using System;
+using System.IO;
+
+namespace MediaBrowser.Model.Serialization
+{
+ public interface IProtobufSerializer
+ {
+ /// <summary>
+ /// Serializes to stream.
+ /// </summary>
+ /// <param name="obj">The obj.</param>
+ /// <param name="stream">The stream.</param>
+ /// <exception cref="System.ArgumentNullException">obj</exception>
+ void SerializeToStream(object obj, Stream stream);
+
+ /// <summary>
+ /// Deserializes from stream.
+ /// </summary>
+ /// <param name="stream">The stream.</param>
+ /// <param name="type">The type.</param>
+ /// <returns>System.Object.</returns>
+ /// <exception cref="System.ArgumentNullException">stream</exception>
+ object DeserializeFromStream(Stream stream, Type type);
+
+ /// <summary>
+ /// Deserializes from stream.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="stream">The stream.</param>
+ /// <returns>``0.</returns>
+ T DeserializeFromStream<T>(Stream stream)
+ where T : class;
+
+ /// <summary>
+ /// Serializes to file.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="obj">The obj.</param>
+ /// <param name="file">The file.</param>
+ /// <exception cref="System.ArgumentNullException">file</exception>
+ void SerializeToFile<T>(T obj, string file);
+
+ /// <summary>
+ /// Deserializes from file.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="file">The file.</param>
+ /// <returns>``0.</returns>
+ /// <exception cref="System.ArgumentNullException">file</exception>
+ T DeserializeFromFile<T>(string file)
+ where T : class;
+
+ /// <summary>
+ /// Serializes to bytes.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="obj">The obj.</param>
+ /// <returns>System.Byte[][].</returns>
+ /// <exception cref="System.ArgumentNullException">obj</exception>
+ byte[] SerializeToBytes<T>(T obj)
+ where T : class;
+ }
+} \ No newline at end of file
diff --git a/MediaBrowser.Model/Serialization/IXmlSerializer.cs b/MediaBrowser.Model/Serialization/IXmlSerializer.cs
new file mode 100644
index 000000000..1d0e0302b
--- /dev/null
+++ b/MediaBrowser.Model/Serialization/IXmlSerializer.cs
@@ -0,0 +1,69 @@
+using System;
+using System.IO;
+
+namespace MediaBrowser.Model.Serialization
+{
+ public interface IXmlSerializer
+ {
+ /// <summary>
+ /// Deserializes from stream.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="stream">The stream.</param>
+ /// <returns>``0.</returns>
+ T DeserializeFromStream<T>(Stream stream);
+
+ /// <summary>
+ /// Deserializes from stream.
+ /// </summary>
+ /// <param name="type">The type.</param>
+ /// <param name="stream">The stream.</param>
+ /// <returns>System.Object.</returns>
+ object DeserializeFromStream(Type type, Stream stream);
+
+ /// <summary>
+ /// Serializes to stream.
+ /// </summary>
+ /// <param name="obj">The obj.</param>
+ /// <param name="stream">The stream.</param>
+ void SerializeToStream(object obj, Stream stream);
+
+ /// <summary>
+ /// Deserializes from file.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="file">The file.</param>
+ /// <returns>``0.</returns>
+ T DeserializeFromFile<T>(string file);
+
+ /// <summary>
+ /// Serializes to file.
+ /// </summary>
+ /// <param name="obj">The obj.</param>
+ /// <param name="file">The file.</param>
+ void SerializeToFile(object obj, string file);
+
+ /// <summary>
+ /// Deserializes from file.
+ /// </summary>
+ /// <param name="type">The type.</param>
+ /// <param name="file">The file.</param>
+ /// <returns>System.Object.</returns>
+ object DeserializeFromFile(Type type, string file);
+
+ /// <summary>
+ /// Deserializes from bytes.
+ /// </summary>
+ /// <param name="type">The type.</param>
+ /// <param name="buffer">The buffer.</param>
+ /// <returns>System.Object.</returns>
+ object DeserializeFromBytes(Type type, byte[] buffer);
+
+ /// <summary>
+ /// Serializes to bytes.
+ /// </summary>
+ /// <param name="obj">The obj.</param>
+ /// <returns>System.Byte[][].</returns>
+ byte[] SerializeToBytes(object obj);
+ }
+} \ No newline at end of file
diff --git a/MediaBrowser.Networking/MediaBrowser.Networking.csproj b/MediaBrowser.Networking/MediaBrowser.Networking.csproj
index 7e4a0b160..41fd6ceab 100644
--- a/MediaBrowser.Networking/MediaBrowser.Networking.csproj
+++ b/MediaBrowser.Networking/MediaBrowser.Networking.csproj
@@ -112,6 +112,8 @@
<Compile Include="Management\NetworkManager.cs" />
<Compile Include="Management\NetworkShares.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Web\ServerFactory.cs" />
+ <Compile Include="Web\NativeWebSocket.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
diff --git a/MediaBrowser.Networking/Web/HttpServer.cs b/MediaBrowser.Networking/Web/HttpServer.cs
index c280abedf..ab4b8558f 100644
--- a/MediaBrowser.Networking/Web/HttpServer.cs
+++ b/MediaBrowser.Networking/Web/HttpServer.cs
@@ -4,6 +4,7 @@ using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Kernel;
using MediaBrowser.Common.Net;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
using ServiceStack.Api.Swagger;
using ServiceStack.Common.Web;
using ServiceStack.Configuration;
@@ -61,6 +62,12 @@ namespace MediaBrowser.Networking.Web
private IDisposable HttpListener { get; set; }
/// <summary>
+ /// Gets or sets the protobuf serializer.
+ /// </summary>
+ /// <value>The protobuf serializer.</value>
+ private IProtobufSerializer ProtobufSerializer { get; set; }
+
+ /// <summary>
/// Occurs when [web socket connected].
/// </summary>
public event EventHandler<WebSocketConnectEventArgs> WebSocketConnected;
@@ -82,17 +89,22 @@ namespace MediaBrowser.Networking.Web
/// </summary>
/// <param name="applicationHost">The application host.</param>
/// <param name="kernel">The kernel.</param>
+ /// <param name="protobufSerializer">The protobuf serializer.</param>
/// <param name="logger">The logger.</param>
/// <param name="serverName">Name of the server.</param>
/// <param name="defaultRedirectpath">The default redirectpath.</param>
/// <exception cref="System.ArgumentNullException">urlPrefix</exception>
- public HttpServer(IApplicationHost applicationHost, IKernel kernel, ILogger logger, string serverName, string defaultRedirectpath)
+ public HttpServer(IApplicationHost applicationHost, IKernel kernel, IProtobufSerializer protobufSerializer, ILogger logger, string serverName, string defaultRedirectpath)
: base()
{
if (kernel == null)
{
throw new ArgumentNullException("kernel");
}
+ if (protobufSerializer == null)
+ {
+ throw new ArgumentNullException("protobufSerializer");
+ }
if (logger == null)
{
throw new ArgumentNullException("logger");
@@ -112,6 +124,7 @@ namespace MediaBrowser.Networking.Web
ServerName = serverName;
DefaultRedirectPath = defaultRedirectpath;
+ ProtobufSerializer = protobufSerializer;
_logger = logger;
ApplicationHost = applicationHost;
@@ -121,7 +134,7 @@ namespace MediaBrowser.Networking.Web
Kernel = kernel;
EndpointHost.ConfigureHost(this, ServerName, CreateServiceManager());
- ContentTypeFilters.Register(ContentType.ProtoBuf, (reqCtx, res, stream) => Kernel.ProtobufSerializer.SerializeToStream(res, stream), (type, stream) => Kernel.ProtobufSerializer.DeserializeFromStream(stream, type));
+ ContentTypeFilters.Register(ContentType.ProtoBuf, (reqCtx, res, stream) => ProtobufSerializer.SerializeToStream(res, stream), (type, stream) => ProtobufSerializer.DeserializeFromStream(stream, type));
Init();
}
@@ -132,6 +145,10 @@ namespace MediaBrowser.Networking.Web
/// <param name="container">The container.</param>
public override void Configure(Container container)
{
+ JsConfig.DateHandler = JsonDateHandler.ISO8601;
+ JsConfig.ExcludeTypeInfo = true;
+ JsConfig.IncludeNullValues = false;
+
SetConfig(new EndpointHostConfig
{
DefaultRedirectPath = DefaultRedirectPath,
diff --git a/MediaBrowser.Common/Net/NativeWebSocket.cs b/MediaBrowser.Networking/Web/NativeWebSocket.cs
index 23f3d4be3..ad28d1a7f 100644
--- a/MediaBrowser.Common/Net/NativeWebSocket.cs
+++ b/MediaBrowser.Networking/Web/NativeWebSocket.cs
@@ -1,7 +1,5 @@
-using MediaBrowser.Common.Serialization;
-using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Logging;
using System;
-using System.IO;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
@@ -79,19 +77,7 @@ namespace MediaBrowser.Common.Net
if (OnReceiveDelegate != null)
{
- using (var memoryStream = new MemoryStream(bytes))
- {
- try
- {
- var messageResult = JsonSerializer.DeserializeFromStream<WebSocketMessageInfo>(memoryStream);
-
- OnReceiveDelegate(messageResult);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error processing web socket message", ex);
- }
- }
+ OnReceiveDelegate(bytes);
}
}
}
@@ -154,6 +140,6 @@ namespace MediaBrowser.Common.Net
/// Gets or sets the receive action.
/// </summary>
/// <value>The receive action.</value>
- public Action<WebSocketMessageInfo> OnReceiveDelegate { get; set; }
+ public Action<byte[]> OnReceiveDelegate { get; set; }
}
}
diff --git a/MediaBrowser.Networking/Web/ServerFactory.cs b/MediaBrowser.Networking/Web/ServerFactory.cs
new file mode 100644
index 000000000..b93f2ca1c
--- /dev/null
+++ b/MediaBrowser.Networking/Web/ServerFactory.cs
@@ -0,0 +1,28 @@
+using MediaBrowser.Common.Kernel;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
+
+namespace MediaBrowser.Networking.Web
+{
+ /// <summary>
+ /// Class ServerFactory
+ /// </summary>
+ public static class ServerFactory
+ {
+ /// <summary>
+ /// Creates the server.
+ /// </summary>
+ /// <param name="applicationHost">The application host.</param>
+ /// <param name="kernel">The kernel.</param>
+ /// <param name="protobufSerializer">The protobuf serializer.</param>
+ /// <param name="logger">The logger.</param>
+ /// <param name="serverName">Name of the server.</param>
+ /// <param name="defaultRedirectpath">The default redirectpath.</param>
+ /// <returns>IHttpServer.</returns>
+ public static IHttpServer CreateServer(IApplicationHost applicationHost, IKernel kernel, IProtobufSerializer protobufSerializer, ILogger logger, string serverName, string defaultRedirectpath)
+ {
+ return new HttpServer(applicationHost, kernel, protobufSerializer, logger, serverName, defaultRedirectpath);
+ }
+ }
+}
diff --git a/MediaBrowser.Networking/WebSocket/AlchemyWebSocket.cs b/MediaBrowser.Networking/WebSocket/AlchemyWebSocket.cs
index fbdb3186f..5eca1a78c 100644
--- a/MediaBrowser.Networking/WebSocket/AlchemyWebSocket.cs
+++ b/MediaBrowser.Networking/WebSocket/AlchemyWebSocket.cs
@@ -1,9 +1,9 @@
using Alchemy.Classes;
using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Serialization;
using MediaBrowser.Model.Logging;
using System;
using System.Net.WebSockets;
+using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -83,9 +83,9 @@ namespace MediaBrowser.Networking.WebSocket
{
try
{
- var messageResult = JsonSerializer.DeserializeFromString<WebSocketMessageInfo>(json);
+ var bytes = Encoding.UTF8.GetBytes(json);
- OnReceiveDelegate(messageResult);
+ OnReceiveDelegate(bytes);
}
catch (Exception ex)
{
@@ -128,6 +128,6 @@ namespace MediaBrowser.Networking.WebSocket
/// Gets or sets the receive action.
/// </summary>
/// <value>The receive action.</value>
- public Action<WebSocketMessageInfo> OnReceiveDelegate { get; set; }
+ public Action<byte[]> OnReceiveDelegate { get; set; }
}
}
diff --git a/MediaBrowser.Server.Sqlite/MediaBrowser.Server.Sqlite.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index 78ea39dd8..416a7d746 100644
--- a/MediaBrowser.Server.Sqlite/MediaBrowser.Server.Sqlite.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -4,11 +4,11 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{8649ED6B-8504-4D00-BFA5-B8C73CC744DB}</ProjectGuid>
+ <ProjectGuid>{2E781478-814D-4A48-9D80-BFF206441A65}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>MediaBrowser.Server.Sqlite</RootNamespace>
- <AssemblyName>MediaBrowser.Server.Sqlite</AssemblyName>
+ <RootNamespace>MediaBrowser.Server.Implementations</RootNamespace>
+ <AssemblyName>MediaBrowser.Server.Implementations</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
@@ -31,9 +31,6 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
- <PropertyGroup>
- <RunPostBuildEvent>Always</RunPostBuildEvent>
- </PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
@@ -43,33 +40,31 @@
<Reference Include="System.Data.SQLite.Linq">
<HintPath>..\packages\System.Data.SQLite.1.0.84.0\lib\net45\System.Data.SQLite.Linq.dll</HintPath>
</Reference>
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="SQLiteDisplayPreferencesRepository.cs" />
- <Compile Include="SQLiteExtensions.cs" />
- <Compile Include="SQLiteItemRepository.cs" />
- <Compile Include="SQLiteRepository.cs" />
- <Compile Include="SQLiteUserDataRepository.cs" />
- <Compile Include="SQLiteUserRepository.cs" />
- </ItemGroup>
- <ItemGroup>
- <Content Include="x64\SQLite.Interop.dll">
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
- </Content>
- <Content Include="x86\SQLite.Interop.dll">
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
- </Content>
- </ItemGroup>
- <ItemGroup>
- <None Include="packages.config" />
+ <Compile Include="ServerApplicationPaths.cs" />
+ <Compile Include="Sqlite\SQLiteDisplayPreferencesRepository.cs" />
+ <Compile Include="Sqlite\SQLiteExtensions.cs" />
+ <Compile Include="Sqlite\SQLiteItemRepository.cs" />
+ <Compile Include="Sqlite\SQLiteRepository.cs" />
+ <Compile Include="Sqlite\SQLiteUserDataRepository.cs" />
+ <Compile Include="Sqlite\SQLiteUserRepository.cs" />
+ <Compile Include="WorldWeatherOnline\WeatherProvider.cs" />
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\MediaBrowser.Common.Implementations\MediaBrowser.Common.Implementations.csproj">
+ <Project>{c4d2573a-3fd3-441f-81af-174ac4cd4e1d}</Project>
+ <Name>MediaBrowser.Common.Implementations</Name>
+ </ProjectReference>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
<Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
<Name>MediaBrowser.Common</Name>
@@ -83,11 +78,20 @@
<Name>MediaBrowser.Model</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <Content Include="x64\SQLite.Interop.dll">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="x86\SQLite.Interop.dll">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
- <PropertyGroup>
- <PostBuildEvent>xcopy "$(TargetPath)" "$(SolutionDir)\MediaBrowser.ServerApplication\CorePlugins\" /y</PostBuildEvent>
- </PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
diff --git a/MediaBrowser.Server.WorldWeatherOnline/Properties/AssemblyInfo.cs b/MediaBrowser.Server.Implementations/Properties/AssemblyInfo.cs
index d5d94bafd..db656b934 100644
--- a/MediaBrowser.Server.WorldWeatherOnline/Properties/AssemblyInfo.cs
+++ b/MediaBrowser.Server.Implementations/Properties/AssemblyInfo.cs
@@ -1,15 +1,14 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-[assembly: AssemblyTitle("MediaBrowser.Server.WorldWeatherOnline")]
+[assembly: AssemblyTitle("MediaBrowser.Server.Implementations")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("MediaBrowser.Server.WorldWeatherOnline")]
+[assembly: AssemblyProduct("MediaBrowser.Server.Implementations")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -20,7 +19,7 @@ using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("c7b294dc-b3fd-4925-9ac3-8dd16803200c")]
+[assembly: Guid("0537cdd3-a069-4d86-9318-d46d8b119903")]
// Version information for an assembly consists of the following four values:
//
@@ -28,4 +27,4 @@ using System.Runtime.InteropServices;
// Minor Version
// Build Number
// Revision
-// \ No newline at end of file
+//
diff --git a/MediaBrowser.Controller/ServerApplicationPaths.cs b/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs
index a376afed8..e473808f5 100644
--- a/MediaBrowser.Controller/ServerApplicationPaths.cs
+++ b/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs
@@ -1,12 +1,13 @@
-using MediaBrowser.Common.Kernel;
+using MediaBrowser.Common.Implementations;
+using MediaBrowser.Controller;
using System.IO;
-namespace MediaBrowser.Controller
+namespace MediaBrowser.Server.Implementations
{
/// <summary>
/// Extends BaseApplicationPaths to add paths that are only applicable on the server
/// </summary>
- public class ServerApplicationPaths : BaseApplicationPaths
+ public class ServerApplicationPaths : BaseApplicationPaths, IServerApplicationPaths
{
/// <summary>
/// The _root folder path
diff --git a/MediaBrowser.Server.Sqlite/SQLiteDisplayPreferencesRepository.cs b/MediaBrowser.Server.Implementations/Sqlite/SQLiteDisplayPreferencesRepository.cs
index 80d389c94..53a467c1a 100644
--- a/MediaBrowser.Server.Sqlite/SQLiteDisplayPreferencesRepository.cs
+++ b/MediaBrowser.Server.Implementations/Sqlite/SQLiteDisplayPreferencesRepository.cs
@@ -1,8 +1,9 @@
-using MediaBrowser.Controller;
+using MediaBrowser.Common.Kernel;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
using System.Data;
@@ -10,7 +11,7 @@ using System.IO;
using System.Threading;
using System.Threading.Tasks;
-namespace MediaBrowser.Server.Sqlite
+namespace MediaBrowser.Server.Implementations.Sqlite
{
/// <summary>
/// Class SQLiteDisplayPreferencesRepository
@@ -35,12 +36,36 @@ namespace MediaBrowser.Server.Sqlite
}
/// <summary>
+ /// The _protobuf serializer
+ /// </summary>
+ private readonly IProtobufSerializer _protobufSerializer;
+
+ /// <summary>
+ /// The _app paths
+ /// </summary>
+ private readonly IApplicationPaths _appPaths;
+
+ /// <summary>
/// Initializes a new instance of the <see cref="SQLiteUserDataRepository" /> class.
/// </summary>
+ /// <param name="appPaths">The app paths.</param>
+ /// <param name="protobufSerializer">The protobuf serializer.</param>
/// <param name="logger">The logger.</param>
- public SQLiteDisplayPreferencesRepository(ILogger logger)
+ /// <exception cref="System.ArgumentNullException">protobufSerializer</exception>
+ public SQLiteDisplayPreferencesRepository(IApplicationPaths appPaths, IProtobufSerializer protobufSerializer, ILogger logger)
: base(logger)
{
+ if (protobufSerializer == null)
+ {
+ throw new ArgumentNullException("protobufSerializer");
+ }
+ if (appPaths == null)
+ {
+ throw new ArgumentNullException("appPaths");
+ }
+
+ _protobufSerializer = protobufSerializer;
+ _appPaths = appPaths;
}
/// <summary>
@@ -49,7 +74,7 @@ namespace MediaBrowser.Server.Sqlite
/// <returns>Task.</returns>
public async Task Initialize()
{
- var dbFile = Path.Combine(Kernel.Instance.ApplicationPaths.DataPath, "displaypreferences.db");
+ var dbFile = Path.Combine(_appPaths.DataPath, "displaypreferences.db");
await ConnectToDB(dbFile).ConfigureAwait(false);
@@ -104,7 +129,7 @@ namespace MediaBrowser.Server.Sqlite
cmd.AddParam("@1", item.DisplayPrefsId);
cmd.AddParam("@2", data.UserId);
- cmd.AddParam("@3", Kernel.Instance.ProtobufSerializer.SerializeToBytes(data));
+ cmd.AddParam("@3", _protobufSerializer.SerializeToBytes(data));
QueueCommand(cmd);
}
@@ -136,7 +161,7 @@ namespace MediaBrowser.Server.Sqlite
{
using (var stream = GetStream(reader, 0))
{
- var data = Kernel.Instance.ProtobufSerializer.DeserializeFromStream<DisplayPreferences>(stream);
+ var data = _protobufSerializer.DeserializeFromStream<DisplayPreferences>(stream);
if (data != null)
{
yield return data;
diff --git a/MediaBrowser.Server.Sqlite/SQLiteExtensions.cs b/MediaBrowser.Server.Implementations/Sqlite/SQLiteExtensions.cs
index f9f79a8b7..6aed8a352 100644
--- a/MediaBrowser.Server.Sqlite/SQLiteExtensions.cs
+++ b/MediaBrowser.Server.Implementations/Sqlite/SQLiteExtensions.cs
@@ -2,7 +2,7 @@
using System.Data;
using System.Data.SQLite;
-namespace MediaBrowser.Server.Sqlite
+namespace MediaBrowser.Server.Implementations.Sqlite
{
/// <summary>
/// Class SQLiteExtensions
diff --git a/MediaBrowser.Server.Sqlite/SQLiteItemRepository.cs b/MediaBrowser.Server.Implementations/Sqlite/SQLiteItemRepository.cs
index 58a924bc4..034cd2188 100644
--- a/MediaBrowser.Server.Sqlite/SQLiteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Sqlite/SQLiteItemRepository.cs
@@ -1,8 +1,8 @@
-using MediaBrowser.Common.Serialization;
-using MediaBrowser.Controller;
+using MediaBrowser.Common.Kernel;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
using System.Data;
@@ -10,7 +10,7 @@ using System.IO;
using System.Threading;
using System.Threading.Tasks;
-namespace MediaBrowser.Server.Sqlite
+namespace MediaBrowser.Server.Implementations.Sqlite
{
/// <summary>
/// Class SQLiteItemRepository
@@ -40,12 +40,37 @@ namespace MediaBrowser.Server.Sqlite
}
/// <summary>
+ /// Gets the json serializer.
+ /// </summary>
+ /// <value>The json serializer.</value>
+ private readonly IJsonSerializer _jsonSerializer;
+
+ /// <summary>
+ /// The _app paths
+ /// </summary>
+ private readonly IApplicationPaths _appPaths;
+
+ /// <summary>
/// Initializes a new instance of the <see cref="SQLiteUserDataRepository" /> class.
/// </summary>
+ /// <param name="appPaths">The app paths.</param>
+ /// <param name="jsonSerializer">The json serializer.</param>
/// <param name="logger">The logger.</param>
- public SQLiteItemRepository(ILogger logger)
+ /// <exception cref="System.ArgumentNullException">appPaths</exception>
+ public SQLiteItemRepository(IApplicationPaths appPaths, IJsonSerializer jsonSerializer, ILogger logger)
: base(logger)
{
+ if (appPaths == null)
+ {
+ throw new ArgumentNullException("appPaths");
+ }
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
+
+ _appPaths = appPaths;
+ _jsonSerializer = jsonSerializer;
}
/// <summary>
@@ -54,7 +79,7 @@ namespace MediaBrowser.Server.Sqlite
/// <returns>Task.</returns>
public async Task Initialize()
{
- var dbFile = Path.Combine(Kernel.Instance.ApplicationPaths.DataPath, "library.db");
+ var dbFile = Path.Combine(_appPaths.DataPath, "library.db");
await ConnectToDB(dbFile).ConfigureAwait(false);
@@ -111,7 +136,7 @@ namespace MediaBrowser.Server.Sqlite
return Task.Run(() =>
{
- var serialized = JsonSerializer.SerializeToBytes(item);
+ var serialized = _jsonSerializer.SerializeToBytes(item);
cancellationToken.ThrowIfCancellationRequested();
@@ -173,7 +198,7 @@ namespace MediaBrowser.Server.Sqlite
return null;
}
- var item = JsonSerializer.DeserializeFromStream(stream, itemType);
+ var item = _jsonSerializer.DeserializeFromStream(stream, itemType);
return item as BaseItem;
}
}
@@ -213,7 +238,7 @@ namespace MediaBrowser.Server.Sqlite
Logger.Error("Cannot find type {0}. Probably belongs to plug-in that is no longer loaded.", type);
continue;
}
- var item = JsonSerializer.DeserializeFromStream(stream, itemType) as BaseItem;
+ var item = _jsonSerializer.DeserializeFromStream(stream, itemType) as BaseItem;
if (item != null)
{
item.Parent = parent;
diff --git a/MediaBrowser.Server.Sqlite/SQLiteRepository.cs b/MediaBrowser.Server.Implementations/Sqlite/SQLiteRepository.cs
index 1caae970e..dead97959 100644
--- a/MediaBrowser.Server.Sqlite/SQLiteRepository.cs
+++ b/MediaBrowser.Server.Implementations/Sqlite/SQLiteRepository.cs
@@ -8,7 +8,7 @@ using System.IO;
using System.Threading;
using System.Threading.Tasks;
-namespace MediaBrowser.Server.Sqlite
+namespace MediaBrowser.Server.Implementations.Sqlite
{
/// <summary>
/// Class SqliteRepository
diff --git a/MediaBrowser.Server.Sqlite/SQLiteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Sqlite/SQLiteUserDataRepository.cs
index eaa89508a..5787a614a 100644
--- a/MediaBrowser.Server.Sqlite/SQLiteUserDataRepository.cs
+++ b/MediaBrowser.Server.Implementations/Sqlite/SQLiteUserDataRepository.cs
@@ -1,7 +1,8 @@
-using MediaBrowser.Controller;
+using MediaBrowser.Common.Kernel;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
using System.Data;
@@ -9,7 +10,7 @@ using System.IO;
using System.Threading;
using System.Threading.Tasks;
-namespace MediaBrowser.Server.Sqlite
+namespace MediaBrowser.Server.Implementations.Sqlite
{
/// <summary>
/// Class SQLiteUserDataRepository
@@ -34,12 +35,36 @@ namespace MediaBrowser.Server.Sqlite
}
/// <summary>
+ /// The _protobuf serializer
+ /// </summary>
+ private readonly IProtobufSerializer _protobufSerializer;
+
+ /// <summary>
+ /// The _app paths
+ /// </summary>
+ private readonly IApplicationPaths _appPaths;
+
+ /// <summary>
/// Initializes a new instance of the <see cref="SQLiteUserDataRepository" /> class.
/// </summary>
+ /// <param name="appPaths">The app paths.</param>
+ /// <param name="protobufSerializer">The protobuf serializer.</param>
/// <param name="logger">The logger.</param>
- public SQLiteUserDataRepository(ILogger logger)
+ /// <exception cref="System.ArgumentNullException">protobufSerializer</exception>
+ public SQLiteUserDataRepository(IApplicationPaths appPaths, IProtobufSerializer protobufSerializer, ILogger logger)
: base(logger)
{
+ if (protobufSerializer == null)
+ {
+ throw new ArgumentNullException("protobufSerializer");
+ }
+ if (appPaths == null)
+ {
+ throw new ArgumentNullException("appPaths");
+ }
+
+ _protobufSerializer = protobufSerializer;
+ _appPaths = appPaths;
}
/// <summary>
@@ -48,7 +73,7 @@ namespace MediaBrowser.Server.Sqlite
/// <returns>Task.</returns>
public async Task Initialize()
{
- var dbFile = Path.Combine(Kernel.Instance.ApplicationPaths.DataPath, "userdata.db");
+ var dbFile = Path.Combine(_appPaths.DataPath, "userdata.db");
await ConnectToDB(dbFile).ConfigureAwait(false);
@@ -103,7 +128,7 @@ namespace MediaBrowser.Server.Sqlite
cmd.AddParam("@1", item.UserDataId);
cmd.AddParam("@2", data.UserId);
- cmd.AddParam("@3", Kernel.Instance.ProtobufSerializer.SerializeToBytes(data));
+ cmd.AddParam("@3", _protobufSerializer.SerializeToBytes(data));
QueueCommand(cmd);
}
@@ -135,7 +160,7 @@ namespace MediaBrowser.Server.Sqlite
{
using (var stream = GetStream(reader, 0))
{
- var data = Kernel.Instance.ProtobufSerializer.DeserializeFromStream<UserItemData>(stream);
+ var data = _protobufSerializer.DeserializeFromStream<UserItemData>(stream);
if (data != null)
{
yield return data;
diff --git a/MediaBrowser.Server.Sqlite/SQLiteUserRepository.cs b/MediaBrowser.Server.Implementations/Sqlite/SQLiteUserRepository.cs
index 6c0de2161..1e6f370eb 100644
--- a/MediaBrowser.Server.Sqlite/SQLiteUserRepository.cs
+++ b/MediaBrowser.Server.Implementations/Sqlite/SQLiteUserRepository.cs
@@ -1,16 +1,16 @@
-using MediaBrowser.Common.Serialization;
-using MediaBrowser.Controller;
+using MediaBrowser.Common.Kernel;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Model.Logging;
-namespace MediaBrowser.Server.Sqlite
+namespace MediaBrowser.Server.Implementations.Sqlite
{
/// <summary>
/// Class SQLiteUserRepository
@@ -35,12 +35,37 @@ namespace MediaBrowser.Server.Sqlite
}
/// <summary>
+ /// Gets the json serializer.
+ /// </summary>
+ /// <value>The json serializer.</value>
+ private readonly IJsonSerializer _jsonSerializer;
+
+ /// <summary>
+ /// The _app paths
+ /// </summary>
+ private readonly IApplicationPaths _appPaths;
+
+ /// <summary>
/// Initializes a new instance of the <see cref="SQLiteUserDataRepository" /> class.
/// </summary>
+ /// <param name="appPaths">The app paths.</param>
+ /// <param name="jsonSerializer">The json serializer.</param>
/// <param name="logger">The logger.</param>
- public SQLiteUserRepository(ILogger logger)
+ /// <exception cref="System.ArgumentNullException">appPaths</exception>
+ public SQLiteUserRepository(IApplicationPaths appPaths, IJsonSerializer jsonSerializer, ILogger logger)
: base(logger)
{
+ if (appPaths == null)
+ {
+ throw new ArgumentNullException("appPaths");
+ }
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
+
+ _appPaths = appPaths;
+ _jsonSerializer = jsonSerializer;
}
/// <summary>
@@ -49,7 +74,7 @@ namespace MediaBrowser.Server.Sqlite
/// <returns>Task.</returns>
public async Task Initialize()
{
- var dbFile = Path.Combine(Kernel.Instance.ApplicationPaths.DataPath, "users.db");
+ var dbFile = Path.Combine(_appPaths.DataPath, "users.db");
await ConnectToDB(dbFile).ConfigureAwait(false);
@@ -88,7 +113,7 @@ namespace MediaBrowser.Server.Sqlite
{
cancellationToken.ThrowIfCancellationRequested();
- var serialized = JsonSerializer.SerializeToBytes(user);
+ var serialized = _jsonSerializer.SerializeToBytes(user);
cancellationToken.ThrowIfCancellationRequested();
@@ -115,7 +140,7 @@ namespace MediaBrowser.Server.Sqlite
{
using (var stream = GetStream(reader, 0))
{
- var user = JsonSerializer.DeserializeFromStream<User>(stream);
+ var user = _jsonSerializer.DeserializeFromStream<User>(stream);
yield return user;
}
}
diff --git a/MediaBrowser.Server.WorldWeatherOnline/WeatherProvider.cs b/MediaBrowser.Server.Implementations/WorldWeatherOnline/WeatherProvider.cs
index c30a30455..1b75a58b8 100644
--- a/MediaBrowser.Server.WorldWeatherOnline/WeatherProvider.cs
+++ b/MediaBrowser.Server.Implementations/WorldWeatherOnline/WeatherProvider.cs
@@ -1,14 +1,14 @@
-using MediaBrowser.Common.Serialization;
-using MediaBrowser.Controller;
+using MediaBrowser.Controller;
using MediaBrowser.Controller.Weather;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Weather;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-namespace MediaBrowser.Server.WorldWeatherOnline
+namespace MediaBrowser.Server.Implementations.WorldWeatherOnline
{
/// <summary>
/// Based on http://www.worldweatheronline.com/free-weather-feed.aspx
@@ -23,17 +23,30 @@ namespace MediaBrowser.Server.WorldWeatherOnline
private ILogger Logger { get; set; }
/// <summary>
+ /// Gets the json serializer.
+ /// </summary>
+ /// <value>The json serializer.</value>
+ protected IJsonSerializer JsonSerializer { get; private set; }
+
+ /// <summary>
/// Initializes a new instance of the <see cref="WeatherProvider" /> class.
/// </summary>
+ /// <param name="jsonSerializer">The json serializer.</param>
/// <param name="logger">The logger.</param>
/// <exception cref="System.ArgumentNullException">logger</exception>
- public WeatherProvider(ILogger logger)
+ public WeatherProvider(IJsonSerializer jsonSerializer, ILogger logger)
{
if (logger == null)
{
throw new ArgumentNullException("logger");
}
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
+
+ JsonSerializer = jsonSerializer;
Logger = logger;
}
diff --git a/MediaBrowser.Server.Sqlite/packages.config b/MediaBrowser.Server.Implementations/packages.config
index 106618814..106618814 100644
--- a/MediaBrowser.Server.Sqlite/packages.config
+++ b/MediaBrowser.Server.Implementations/packages.config
diff --git a/MediaBrowser.ServerApplication/App.xaml.cs b/MediaBrowser.ServerApplication/App.xaml.cs
index 1b6b6f98e..5808120ad 100644
--- a/MediaBrowser.ServerApplication/App.xaml.cs
+++ b/MediaBrowser.ServerApplication/App.xaml.cs
@@ -1,26 +1,13 @@
-using BDInfo;
-using MediaBrowser.ClickOnce;
-using MediaBrowser.Common.IO;
+using MediaBrowser.ClickOnce;
+using MediaBrowser.Common.Implementations.Serialization;
using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Net;
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.Updates;
-using MediaBrowser.Networking.Management;
-using MediaBrowser.Networking.Udp;
-using MediaBrowser.Networking.Web;
-using MediaBrowser.Networking.WebSocket;
using MediaBrowser.Server.Uninstall;
-using MediaBrowser.ServerApplication.Implementations;
using Microsoft.Win32;
-using SimpleInjector;
using System;
using System.Diagnostics;
-using System.IO;
using System.Linq;
using System.Net.Cache;
using System.Threading;
@@ -35,7 +22,7 @@ namespace MediaBrowser.ServerApplication
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
- public partial class App : Application, IApplicationHost
+ public partial class App : Application
{
/// <summary>
/// Defines the entry point of the application.
@@ -78,16 +65,11 @@ namespace MediaBrowser.ServerApplication
protected ILogger Logger { get; set; }
/// <summary>
- /// Gets or sets the log file path.
+ /// Gets or sets the composition root.
/// </summary>
- /// <value>The log file path.</value>
- public string LogFilePath { get; private set; }
-
- /// <summary>
- /// The container
- /// </summary>
- private Container _container = new Container();
-
+ /// <value>The composition root.</value>
+ protected ApplicationHost CompositionRoot { get; set; }
+
/// <summary>
/// Initializes a new instance of the <see cref="App" /> class.
/// </summary>
@@ -136,12 +118,6 @@ namespace MediaBrowser.ServerApplication
}
/// <summary>
- /// Gets or sets the iso manager.
- /// </summary>
- /// <value>The iso manager.</value>
- private IIsoManager IsoManager { get; set; }
-
- /// <summary>
/// Gets or sets a value indicating whether [last run at startup value].
/// </summary>
/// <value><c>null</c> if [last run at startup value] contains no value, <c>true</c> if [last run at startup value]; otherwise, <c>false</c>.</value>
@@ -198,13 +174,13 @@ namespace MediaBrowser.ServerApplication
/// </summary>
protected async void LoadKernel()
{
- Kernel = new Kernel(this, Logger);
+ CompositionRoot = new ApplicationHost(Logger);
- RegisterResources();
+ Kernel = CompositionRoot.Kernel;
try
{
- new MainWindow(Logger).Show();
+ new MainWindow(new JsonSerializer(), Logger).Show();
var now = DateTime.UtcNow;
@@ -281,6 +257,7 @@ namespace MediaBrowser.ServerApplication
base.OnExit(e);
Kernel.Dispose();
+ CompositionRoot.Dispose();
}
/// <summary>
@@ -392,17 +369,6 @@ namespace MediaBrowser.ServerApplication
}
/// <summary>
- /// Reloads the logger.
- /// </summary>
- /// <exception cref="System.NotImplementedException"></exception>
- public void ReloadLogger()
- {
- LogFilePath = Path.Combine(Kernel.ApplicationPaths.LogDirectoryPath, "Server-" + DateTime.Now.Ticks + ".log");
-
- NlogManager.AddFileTarget(LogFilePath, Kernel.Configuration.EnableDebugLevelLogging);
- }
-
- /// <summary>
/// Gets the image.
/// </summary>
/// <param name="uri">The URI.</param>
@@ -477,143 +443,5 @@ namespace MediaBrowser.ServerApplication
RenderOptions.SetBitmapScalingMode(bitmap, BitmapScalingMode.Fant);
return bitmap;
}
-
- /// <summary>
- /// Gets or sets a value indicating whether this instance can self update.
- /// </summary>
- /// <value><c>true</c> if this instance can self update; otherwise, <c>false</c>.</value>
- public bool CanSelfUpdate
- {
- get { return ClickOnceHelper.IsNetworkDeployed; }
- }
-
- /// <summary>
- /// Checks for update.
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="progress">The progress.</param>
- /// <returns>Task{CheckForUpdateResult}.</returns>
- public Task<CheckForUpdateResult> CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress<double> progress)
- {
- return new ApplicationUpdateCheck().CheckForApplicationUpdate(cancellationToken, progress);
- }
-
- /// <summary>
- /// Updates the application.
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="progress">The progress.</param>
- /// <returns>Task.</returns>
- public Task UpdateApplication(CancellationToken cancellationToken, IProgress<double> progress)
- {
- return new ApplicationUpdater().UpdateApplication(cancellationToken, progress);
- }
-
- /// <summary>
- /// Registers resources that classes will depend on
- /// </summary>
- private void RegisterResources()
- {
- RegisterSingleInstance<IApplicationHost>(this);
- RegisterSingleInstance(Logger);
-
- IsoManager = new PismoIsoManager(Logger);
-
- RegisterSingleInstance(IsoManager);
- RegisterSingleInstance<IBlurayExaminer>(() => new BdInfoExaminer());
- RegisterSingleInstance<INetworkManager>(() => new NetworkManager());
- RegisterSingleInstance<IZipClient>(() => new DotNetZipClient());
- RegisterSingleInstance<IWebSocketServer>(() => new AlchemyServer(Logger));
- Register(typeof(IUdpServer), typeof(UdpServer));
- RegisterSingleInstance<IHttpServer>(() => new HttpServer(this, Kernel, Logger, "Media Browser", "index.html"));
- }
-
- /// <summary>
- /// Creates an instance of type and resolves all constructor dependancies
- /// </summary>
- /// <param name="type">The type.</param>
- /// <returns>System.Object.</returns>
- public object CreateInstance(Type type)
- {
- try
- {
- return _container.GetInstance(type);
- }
- catch
- {
- Logger.Error("Error creating {0}", type.Name);
-
- throw;
- }
- }
-
- /// <summary>
- /// Registers the specified obj.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="obj">The obj.</param>
- public void RegisterSingleInstance<T>(T obj)
- where T : class
- {
- _container.RegisterSingle(obj);
- }
-
- /// <summary>
- /// Registers the specified func.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="func">The func.</param>
- public void Register<T>(Func<T> func)
- where T : class
- {
- _container.Register(func);
- }
-
- /// <summary>
- /// Registers the single instance.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="func">The func.</param>
- public void RegisterSingleInstance<T>(Func<T> func)
- where T : class
- {
- _container.RegisterSingle(func);
- }
-
- /// <summary>
- /// Resolves this instance.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <returns>``0.</returns>
- public T Resolve<T>()
- {
- return (T)_container.GetRegistration(typeof(T), true).GetInstance();
- }
-
- /// <summary>
- /// Resolves this instance.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <returns>``0.</returns>
- public T TryResolve<T>()
- {
- var result = _container.GetRegistration(typeof(T), false);
-
- if (result == null)
- {
- return default(T);
- }
- return (T)result.GetInstance();
- }
-
- /// <summary>
- /// Registers the specified service type.
- /// </summary>
- /// <param name="serviceType">Type of the service.</param>
- /// <param name="implementation">Type of the concrete.</param>
- public void Register(Type serviceType, Type implementation)
- {
- _container.Register(serviceType, implementation);
- }
}
}
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
new file mode 100644
index 000000000..40e190756
--- /dev/null
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -0,0 +1,498 @@
+using BDInfo;
+using MediaBrowser.ClickOnce;
+using MediaBrowser.Common.Implementations.ScheduledTasks;
+using MediaBrowser.Common.Implementations.Serialization;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Kernel;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Common.ScheduledTasks;
+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;
+using MediaBrowser.Model.Updates;
+using MediaBrowser.Networking.Management;
+using MediaBrowser.Networking.Udp;
+using MediaBrowser.Networking.Web;
+using MediaBrowser.Networking.WebSocket;
+using MediaBrowser.Server.Implementations;
+using MediaBrowser.ServerApplication.Implementations;
+using SimpleInjector;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.ServerApplication
+{
+ /// <summary>
+ /// Class CompositionRoot
+ /// </summary>
+ public class ApplicationHost : IApplicationHost, IDisposable
+ {
+ /// <summary>
+ /// Gets or sets the logger.
+ /// </summary>
+ /// <value>The logger.</value>
+ private ILogger Logger { get; set; }
+
+ /// <summary>
+ /// Gets or sets the iso manager.
+ /// </summary>
+ /// <value>The iso manager.</value>
+ private IIsoManager IsoManager { get; set; }
+
+ /// <summary>
+ /// Gets or sets the log file path.
+ /// </summary>
+ /// <value>The log file path.</value>
+ public string LogFilePath { get; private set; }
+
+ /// <summary>
+ /// The container
+ /// </summary>
+ private readonly Container _container = new Container();
+
+ /// <summary>
+ /// Gets or sets the kernel.
+ /// </summary>
+ /// <value>The kernel.</value>
+ public Kernel Kernel { get; private set; }
+
+ private readonly List<string> _failedAssemblies = new List<string>();
+ /// <summary>
+ /// Gets assemblies that failed to load
+ /// </summary>
+ public IEnumerable<string> FailedAssemblies
+ {
+ get { return _failedAssemblies; }
+ }
+
+ /// <summary>
+ /// Gets all types within all running assemblies
+ /// </summary>
+ /// <value>All types.</value>
+ public Type[] AllTypes { get; private set; }
+
+ /// <summary>
+ /// Gets all concrete types.
+ /// </summary>
+ /// <value>All concrete types.</value>
+ public Type[] AllConcreteTypes { get; private set; }
+
+ /// <summary>
+ /// The disposable parts
+ /// </summary>
+ private readonly List<IDisposable> _disposableParts = new List<IDisposable>();
+
+ /// <summary>
+ /// The json serializer
+ /// </summary>
+ private readonly IJsonSerializer _jsonSerializer = new JsonSerializer();
+
+ /// <summary>
+ /// The _XML serializer
+ /// </summary>
+ private readonly IXmlSerializer _xmlSerializer = new XmlSerializer();
+
+ /// <summary>
+ /// The _application paths
+ /// </summary>
+ private readonly IServerApplicationPaths _applicationPaths = new ServerApplicationPaths();
+
+ /// <summary>
+ /// The _task manager
+ /// </summary>
+ private readonly ITaskManager _taskManager;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ApplicationHost" /> class.
+ /// </summary>
+ /// <param name="logger">The logger.</param>
+ public ApplicationHost(ILogger logger)
+ {
+ Logger = logger;
+
+ _taskManager = new TaskManager(_applicationPaths, _jsonSerializer, Logger);
+
+ Kernel = new Kernel(this, _applicationPaths, _xmlSerializer, _taskManager, Logger);
+
+ RegisterResources();
+
+ FindParts();
+ }
+
+ /// <summary>
+ /// Registers resources that classes will depend on
+ /// </summary>
+ internal void RegisterResources()
+ {
+ DiscoverTypes();
+
+ RegisterSingleInstance<IKernel>(Kernel);
+ RegisterSingleInstance(Kernel);
+
+ RegisterSingleInstance<IApplicationHost>(this);
+ RegisterSingleInstance(Logger);
+
+ IsoManager = new PismoIsoManager(Logger);
+
+ RegisterSingleInstance(_applicationPaths);
+ RegisterSingleInstance<IApplicationPaths>(_applicationPaths);
+
+ RegisterSingleInstance(IsoManager);
+ RegisterSingleInstance(_taskManager);
+ RegisterSingleInstance<IBlurayExaminer>(() => new BdInfoExaminer());
+ RegisterSingleInstance<INetworkManager>(() => new NetworkManager());
+ RegisterSingleInstance<IZipClient>(() => new DotNetZipClient());
+ RegisterSingleInstance<IWebSocketServer>(() => new AlchemyServer(Logger));
+ RegisterSingleInstance(_jsonSerializer);
+ RegisterSingleInstance(_xmlSerializer);
+ RegisterSingleInstance<IProtobufSerializer>(() => ProtobufSerializer);
+ Register(typeof(IUdpServer), typeof(UdpServer));
+ RegisterSingleInstance(() => ServerFactory.CreateServer(this, Kernel, ProtobufSerializer, Logger, "Media Browser", "index.html"));
+ }
+
+ /// <summary>
+ /// Discovers the types.
+ /// </summary>
+ private void DiscoverTypes()
+ {
+ _failedAssemblies.Clear();
+
+ AllTypes = GetComposablePartAssemblies().SelectMany(GetTypes).ToArray();
+
+ AllConcreteTypes = AllTypes.Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType).ToArray();
+ }
+
+ /// <summary>
+ /// Finds the parts.
+ /// </summary>
+ private void FindParts()
+ {
+ _taskManager.AddTasks(GetExports<IScheduledTask>(false));
+ }
+
+ /// <summary>
+ /// Gets a list of types within an assembly
+ /// This will handle situations that would normally throw an exception - such as a type within the assembly that depends on some other non-existant reference
+ /// </summary>
+ /// <param name="assembly">The assembly.</param>
+ /// <returns>IEnumerable{Type}.</returns>
+ /// <exception cref="System.ArgumentNullException">assembly</exception>
+ private IEnumerable<Type> GetTypes(Assembly assembly)
+ {
+ if (assembly == null)
+ {
+ throw new ArgumentNullException("assembly");
+ }
+
+ try
+ {
+ return assembly.GetTypes();
+ }
+ catch (ReflectionTypeLoadException ex)
+ {
+ // If it fails we can still get a list of the Types it was able to resolve
+ return ex.Types.Where(t => t != null);
+ }
+ }
+
+ /// <summary>
+ /// The _protobuf serializer initialized
+ /// </summary>
+ private bool _protobufSerializerInitialized;
+ /// <summary>
+ /// The _protobuf serializer sync lock
+ /// </summary>
+ private object _protobufSerializerSyncLock = new object();
+ /// <summary>
+ /// Gets a dynamically compiled generated serializer that can serialize protocontracts without reflection
+ /// </summary>
+ private ProtobufSerializer _protobufSerializer;
+ /// <summary>
+ /// Gets the protobuf serializer.
+ /// </summary>
+ /// <value>The protobuf serializer.</value>
+ public ProtobufSerializer ProtobufSerializer
+ {
+ get
+ {
+ // Lazy load
+ LazyInitializer.EnsureInitialized(ref _protobufSerializer, ref _protobufSerializerInitialized, ref _protobufSerializerSyncLock, () => ProtobufSerializer.Create(AllTypes));
+ return _protobufSerializer;
+ }
+ private set
+ {
+ _protobufSerializer = value;
+ _protobufSerializerInitialized = value != null;
+ }
+ }
+
+ /// <summary>
+ /// Creates an instance of type and resolves all constructor dependancies
+ /// </summary>
+ /// <param name="type">The type.</param>
+ /// <returns>System.Object.</returns>
+ public object CreateInstance(Type type)
+ {
+ try
+ {
+ return _container.GetInstance(type);
+ }
+ catch
+ {
+ Logger.Error("Error creating {0}", type.Name);
+
+ throw;
+ }
+ }
+
+ /// <summary>
+ /// Registers the specified obj.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="obj">The obj.</param>
+ public void RegisterSingleInstance<T>(T obj)
+ where T : class
+ {
+ _container.RegisterSingle(obj);
+ }
+
+ /// <summary>
+ /// Registers the specified func.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="func">The func.</param>
+ public void Register<T>(Func<T> func)
+ where T : class
+ {
+ _container.Register(func);
+ }
+
+ /// <summary>
+ /// Registers the single instance.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="func">The func.</param>
+ public void RegisterSingleInstance<T>(Func<T> func)
+ where T : class
+ {
+ _container.RegisterSingle(func);
+ }
+
+ /// <summary>
+ /// Resolves this instance.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns>``0.</returns>
+ public T Resolve<T>()
+ {
+ return (T)_container.GetRegistration(typeof(T), true).GetInstance();
+ }
+
+ /// <summary>
+ /// Resolves this instance.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns>``0.</returns>
+ public T TryResolve<T>()
+ {
+ var result = _container.GetRegistration(typeof(T), false);
+
+ if (result == null)
+ {
+ return default(T);
+ }
+ return (T)result.GetInstance();
+ }
+
+ /// <summary>
+ /// Registers the specified service type.
+ /// </summary>
+ /// <param name="serviceType">Type of the service.</param>
+ /// <param name="implementation">Type of the concrete.</param>
+ public void Register(Type serviceType, Type implementation)
+ {
+ _container.Register(serviceType, implementation);
+ }
+
+ /// <summary>
+ /// Restarts this instance.
+ /// </summary>
+ /// <exception cref="System.NotImplementedException"></exception>
+ public void Restart()
+ {
+ App.Instance.Restart();
+ }
+
+ /// <summary>
+ /// Reloads the logger.
+ /// </summary>
+ /// <exception cref="System.NotImplementedException"></exception>
+ public void ReloadLogger()
+ {
+ LogFilePath = Path.Combine(Kernel.ApplicationPaths.LogDirectoryPath, "Server-" + DateTime.Now.Ticks + ".log");
+
+ NlogManager.AddFileTarget(LogFilePath, Kernel.Configuration.EnableDebugLevelLogging);
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance can self update.
+ /// </summary>
+ /// <value><c>true</c> if this instance can self update; otherwise, <c>false</c>.</value>
+ public bool CanSelfUpdate
+ {
+ get { return ClickOnceHelper.IsNetworkDeployed; }
+ }
+
+ /// <summary>
+ /// Checks for update.
+ /// </summary>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <param name="progress">The progress.</param>
+ /// <returns>Task{CheckForUpdateResult}.</returns>
+ public Task<CheckForUpdateResult> CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress<double> progress)
+ {
+ return new ApplicationUpdateCheck().CheckForApplicationUpdate(cancellationToken, progress);
+ }
+
+ /// <summary>
+ /// Updates the application.
+ /// </summary>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <param name="progress">The progress.</param>
+ /// <returns>Task.</returns>
+ public Task UpdateApplication(CancellationToken cancellationToken, IProgress<double> progress)
+ {
+ return new ApplicationUpdater().UpdateApplication(cancellationToken, progress);
+ }
+
+ /// <summary>
+ /// Gets the composable part assemblies.
+ /// </summary>
+ /// <returns>IEnumerable{Assembly}.</returns>
+ private IEnumerable<Assembly> GetComposablePartAssemblies()
+ {
+ // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that
+ // This will prevent the .dll file from getting locked, and allow us to replace it when needed
+ foreach (var pluginAssembly in Directory
+ .EnumerateFiles(Kernel.ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly)
+ .Select(LoadAssembly).Where(a => a != null))
+ {
+ yield return pluginAssembly;
+ }
+
+ var runningDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
+ var corePluginDirectory = Path.Combine(runningDirectory, "CorePlugins");
+
+ // This will prevent the .dll file from getting locked, and allow us to replace it when needed
+ foreach (var pluginAssembly in Directory
+ .EnumerateFiles(corePluginDirectory, "*.dll", SearchOption.TopDirectoryOnly)
+ .Select(LoadAssembly).Where(a => a != null))
+ {
+ yield return pluginAssembly;
+ }
+
+ // Include composable parts in the Model assembly
+ yield return typeof(SystemInfo).Assembly;
+
+ // Include composable parts in the Common assembly
+ yield return typeof(IKernel).Assembly;
+
+ // Include composable parts in the Controller assembly
+ yield return typeof(Kernel).Assembly;
+
+ // Common implementations
+ yield return typeof(TaskManager).Assembly;
+
+ // Server implementations
+ yield return typeof(ServerApplicationPaths).Assembly;
+
+ // Include composable parts in the running assembly
+ yield return GetType().Assembly;
+ }
+
+ /// <summary>
+ /// Loads the assembly.
+ /// </summary>
+ /// <param name="file">The file.</param>
+ /// <returns>Assembly.</returns>
+ private Assembly LoadAssembly(string file)
+ {
+ try
+ {
+ return Assembly.Load(File.ReadAllBytes((file)));
+ }
+ catch (Exception ex)
+ {
+ _failedAssemblies.Add(file);
+ Logger.ErrorException("Error loading assembly {0}", ex, file);
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Gets the exports.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="allTypes">All types.</param>
+ /// <param name="manageLiftime">if set to <c>true</c> [manage liftime].</param>
+ /// <returns>IEnumerable{``0}.</returns>
+ public IEnumerable<T> GetExports<T>(bool manageLiftime = true)
+ {
+ var currentType = typeof(T);
+
+ Logger.Info("Composing instances of " + currentType.Name);
+
+ var parts = AllConcreteTypes.Where(currentType.IsAssignableFrom).Select(CreateInstance).Cast<T>().ToArray();
+
+ if (manageLiftime)
+ {
+ _disposableParts.AddRange(parts.OfType<IDisposable>());
+ }
+
+ return parts;
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources.
+ /// </summary>
+ /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+ protected virtual void Dispose(bool dispose)
+ {
+ IsoManager.Dispose();
+
+ foreach (var part in _disposableParts)
+ {
+ part.Dispose();
+ }
+
+ _disposableParts.Clear();
+ }
+ }
+
+ public class MyClass
+ {
+ public MyClass()
+ {
+
+ }
+ }
+}
diff --git a/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs b/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs
index 02dd6fb9c..59961a941 100644
--- a/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs
+++ b/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs
@@ -1,11 +1,12 @@
-using MediaBrowser.Common.Serialization;
-using MediaBrowser.Controller;
+using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -18,7 +19,6 @@ using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media.Imaging;
-using MediaBrowser.Model.Logging;
namespace MediaBrowser.ServerApplication
{
@@ -27,8 +27,10 @@ namespace MediaBrowser.ServerApplication
/// </summary>
public partial class LibraryExplorer : Window
{
- private ILogger _logger;
+ private readonly ILogger _logger;
+ private readonly IJsonSerializer _jsonSerializer;
+
/// <summary>
/// The current user
/// </summary>
@@ -36,9 +38,10 @@ namespace MediaBrowser.ServerApplication
/// <summary>
/// Initializes a new instance of the <see cref="LibraryExplorer" /> class.
/// </summary>
- public LibraryExplorer(ILogger logger)
+ public LibraryExplorer(IJsonSerializer jsonSerializer, ILogger logger)
{
_logger = logger;
+ _jsonSerializer = jsonSerializer;
InitializeComponent();
lblVersion.Content = "Version: " + Kernel.Instance.ApplicationVersion;
@@ -161,7 +164,7 @@ namespace MediaBrowser.ServerApplication
lblIndexBy.Visibility = ddlIndexBy.Visibility = ddlSortBy.Visibility = lblSortBy.Visibility = Visibility.Hidden;
}
- txtData.Text = FormatJson(JsonSerializer.SerializeToString(item)) + trailers + features;
+ txtData.Text = FormatJson(_jsonSerializer.SerializeToString(item)) + trailers + features;
var previews = new List<PreviewItem>();
await Task.Run(() =>
diff --git a/MediaBrowser.ServerApplication/MainWindow.xaml.cs b/MediaBrowser.ServerApplication/MainWindow.xaml.cs
index 8a312e7ef..332bb1daa 100644
--- a/MediaBrowser.ServerApplication/MainWindow.xaml.cs
+++ b/MediaBrowser.ServerApplication/MainWindow.xaml.cs
@@ -2,6 +2,7 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
using MediaBrowser.ServerApplication.Controls;
using MediaBrowser.ServerApplication.Logging;
using System;
@@ -39,6 +40,11 @@ namespace MediaBrowser.ServerApplication
private Timer NewItemTimer { get; set; }
/// <summary>
+ /// The _json serializer
+ /// </summary>
+ private readonly IJsonSerializer _jsonSerializer;
+
+ /// <summary>
/// The _logger
/// </summary>
private readonly ILogger _logger;
@@ -48,13 +54,18 @@ namespace MediaBrowser.ServerApplication
/// </summary>
/// <param name="logger">The logger.</param>
/// <exception cref="System.ArgumentNullException">logger</exception>
- public MainWindow(ILogger logger)
+ public MainWindow(IJsonSerializer jsonSerializer, ILogger logger)
{
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
if (logger == null)
{
throw new ArgumentNullException("logger");
}
+ _jsonSerializer = jsonSerializer;
_logger = logger;
InitializeComponent();
@@ -282,7 +293,7 @@ namespace MediaBrowser.ServerApplication
/// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param>
private void cmOpenExplorer_click(object sender, RoutedEventArgs e)
{
- (new LibraryExplorer(_logger)).Show();
+ (new LibraryExplorer(_jsonSerializer, _logger)).Show();
}
/// <summary>
diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
index b1c57949c..8a3a0b7af 100644
--- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
+++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
@@ -128,36 +128,6 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\ThirdParty\UPnP\Libs\Platinum.Managed.dll</HintPath>
</Reference>
- <Reference Include="ServiceStack, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\ServiceStack.3.9.37\lib\net35\ServiceStack.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.Common, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Common.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.Interfaces, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Interfaces.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.OrmLite, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\ServiceStack.OrmLite.SqlServer.3.9.37\lib\ServiceStack.OrmLite.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.OrmLite.SqlServer">
- <HintPath>..\packages\ServiceStack.OrmLite.SqlServer.3.9.37\lib\ServiceStack.OrmLite.SqlServer.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.Redis">
- <HintPath>..\packages\ServiceStack.Redis.3.9.37\lib\net35\ServiceStack.Redis.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.ServiceInterface, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\ServiceStack.3.9.37\lib\net35\ServiceStack.ServiceInterface.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.Text, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\ServiceStack.Text.3.9.37\lib\net35\ServiceStack.Text.dll</HintPath>
- </Reference>
<Reference Include="SimpleInjector, Version=2.0.0.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SimpleInjector.2.0.0-beta5\lib\net40-client\SimpleInjector.dll</HintPath>
@@ -220,6 +190,7 @@
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
+ <Compile Include="ApplicationHost.cs" />
<Compile Include="Controls\ItemUpdateNotification.xaml.cs">
<DependentUpon>ItemUpdateNotification.xaml</DependentUpon>
</Compile>
@@ -279,6 +250,10 @@
<Project>{cc96bf3e-0bda-4809-bc4b-bb6d418f4a84}</Project>
<Name>MediaBrowser.ClickOnce</Name>
</ProjectReference>
+ <ProjectReference Include="..\MediaBrowser.Common.Implementations\MediaBrowser.Common.Implementations.csproj">
+ <Project>{c4d2573a-3fd3-441f-81af-174ac4cd4e1d}</Project>
+ <Name>MediaBrowser.Common.Implementations</Name>
+ </ProjectReference>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
<Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
<Name>MediaBrowser.Common</Name>
@@ -303,6 +278,10 @@
<Project>{7c11010e-179a-49b7-bfb2-f1656f5e71ad}</Project>
<Name>MediaBrowser.Networking</Name>
</ProjectReference>
+ <ProjectReference Include="..\MediaBrowser.Server.Implementations\MediaBrowser.Server.Implementations.csproj">
+ <Project>{2e781478-814d-4a48-9d80-bff206441a65}</Project>
+ <Name>MediaBrowser.Server.Implementations</Name>
+ </ProjectReference>
<ProjectReference Include="..\MediaBrowser.Server.Uninstall\MediaBrowser.Server.Uninstall.csproj">
<Project>{5443422f-9548-417a-90dd-2fc91f2b5999}</Project>
<Name>MediaBrowser.Server.Uninstall</Name>
diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config
index 28d6202f8..e1beae6da 100644
--- a/MediaBrowser.ServerApplication/packages.config
+++ b/MediaBrowser.ServerApplication/packages.config
@@ -3,11 +3,6 @@
<package id="DotNetZip" version="1.9.1.8" targetFramework="net45" />
<package id="Hardcodet.Wpf.TaskbarNotification" version="1.0.4.0" targetFramework="net45" />
<package id="NLog" version="2.0.0.2000" targetFramework="net45" />
- <package id="ServiceStack" version="3.9.37" targetFramework="net45" />
- <package id="ServiceStack.Common" version="3.9.37" targetFramework="net45" />
- <package id="ServiceStack.OrmLite.SqlServer" version="3.9.37" targetFramework="net45" />
- <package id="ServiceStack.Redis" version="3.9.37" targetFramework="net45" />
- <package id="ServiceStack.Text" version="3.9.37" targetFramework="net45" />
<package id="SimpleInjector" version="2.0.0-beta5" targetFramework="net45" />
<package id="System.Data.SQLite" version="1.0.84.0" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs
index aca931306..b321cc8d9 100644
--- a/MediaBrowser.WebDashboard/Api/DashboardService.cs
+++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs
@@ -1,7 +1,6 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Common.ScheduledTasks;
-using MediaBrowser.Common.ScheduledTasks.Tasks;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Plugins;
@@ -137,7 +136,7 @@ namespace MediaBrowser.WebDashboard.Api
.Select(ScheduledTaskHelpers.GetTaskInfo)
.ToArray(),
- ApplicationUpdateTaskId = taskManager.ScheduledTasks.OfType<SystemUpdateTask>().First().Id,
+ ApplicationUpdateTaskId = taskManager.ScheduledTasks.First(t => t.GetType().Name.Equals("SystemUpdateTask", StringComparison.OrdinalIgnoreCase)).Id,
ActiveConnections = connections,
diff --git a/MediaBrowser.sln b/MediaBrowser.sln
index 3f053e2d8..9ce346417 100644
--- a/MediaBrowser.sln
+++ b/MediaBrowser.sln
@@ -20,8 +20,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
Performance19.psess = Performance19.psess
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.ApiInteraction.Javascript", "MediaBrowser.ApiInteraction.Javascript\MediaBrowser.ApiInteraction.Javascript.csproj", "{767B536E-D90C-4D74-A14B-8564B16F3499}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.ApiInteraction", "MediaBrowser.ApiInteraction\MediaBrowser.ApiInteraction.csproj", "{921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.ApiInteraction.Portable", "MediaBrowser.ApiInteraction.Portable\MediaBrowser.ApiInteraction.Portable.csproj", "{52E0C440-85C0-4A99-ACFE-07C87B2600BE}"
@@ -41,10 +39,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.IsoMounter", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Installer", "MediaBrowser.Installer\MediaBrowser.Installer.csproj", "{3879F78A-D6F6-45E5-B2A8-D8DCF2DABB74}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.Sqlite", "MediaBrowser.Server.Sqlite\MediaBrowser.Server.Sqlite.csproj", "{8649ED6B-8504-4D00-BFA5-B8C73CC744DB}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.WorldWeatherOnline", "MediaBrowser.Server.WorldWeatherOnline\MediaBrowser.Server.WorldWeatherOnline.csproj", "{973CA45C-8362-490B-8327-C68098FD4891}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Logging.NLog", "MediaBrowser.Logging.NLog\MediaBrowser.Logging.NLog.csproj", "{67310740-0EC4-4DC2-9921-33DF38B20167}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.ClickOnce", "MediaBrowser.ClickOnce\MediaBrowser.ClickOnce.csproj", "{CC96BF3E-0BDA-4809-BC4B-BB6D418F4A84}"
@@ -53,6 +47,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Networking", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Uninstaller", "MediaBrowser.Uninstaller\MediaBrowser.Uninstaller.csproj", "{FACAF749-3E28-46DD-B613-654FCD434959}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Common.Implementations", "MediaBrowser.Common.Implementations\MediaBrowser.Common.Implementations.csproj", "{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.Implementations", "MediaBrowser.Server.Implementations\MediaBrowser.Server.Implementations.csproj", "{2E781478-814D-4A48-9D80-BFF206441A65}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -163,21 +161,6 @@ Global
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x64.ActiveCfg = Release|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x86.ActiveCfg = Release|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x86.Build.0 = Release|Any CPU
- {767B536E-D90C-4D74-A14B-8564B16F3499}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {767B536E-D90C-4D74-A14B-8564B16F3499}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {767B536E-D90C-4D74-A14B-8564B16F3499}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {767B536E-D90C-4D74-A14B-8564B16F3499}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {767B536E-D90C-4D74-A14B-8564B16F3499}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {767B536E-D90C-4D74-A14B-8564B16F3499}.Debug|x64.ActiveCfg = Debug|Any CPU
- {767B536E-D90C-4D74-A14B-8564B16F3499}.Debug|x86.ActiveCfg = Debug|Any CPU
- {767B536E-D90C-4D74-A14B-8564B16F3499}.Debug|x86.Build.0 = Debug|Any CPU
- {767B536E-D90C-4D74-A14B-8564B16F3499}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {767B536E-D90C-4D74-A14B-8564B16F3499}.Release|Any CPU.Build.0 = Release|Any CPU
- {767B536E-D90C-4D74-A14B-8564B16F3499}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {767B536E-D90C-4D74-A14B-8564B16F3499}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {767B536E-D90C-4D74-A14B-8564B16F3499}.Release|Win32.ActiveCfg = Release|Any CPU
- {767B536E-D90C-4D74-A14B-8564B16F3499}.Release|x64.ActiveCfg = Release|Any CPU
- {767B536E-D90C-4D74-A14B-8564B16F3499}.Release|x86.ActiveCfg = Release|Any CPU
{921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Debug|Any CPU.Build.0 = Debug|Any CPU
{921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -266,34 +249,6 @@ Global
{3879F78A-D6F6-45E5-B2A8-D8DCF2DABB74}.Release|Win32.ActiveCfg = Release|Any CPU
{3879F78A-D6F6-45E5-B2A8-D8DCF2DABB74}.Release|x64.ActiveCfg = Release|Any CPU
{3879F78A-D6F6-45E5-B2A8-D8DCF2DABB74}.Release|x86.ActiveCfg = Release|Any CPU
- {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Debug|x64.ActiveCfg = Debug|Any CPU
- {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Debug|x86.ActiveCfg = Debug|Any CPU
- {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Release|Any CPU.Build.0 = Release|Any CPU
- {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Release|Win32.ActiveCfg = Release|Any CPU
- {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Release|x64.ActiveCfg = Release|Any CPU
- {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Release|x86.ActiveCfg = Release|Any CPU
- {973CA45C-8362-490B-8327-C68098FD4891}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {973CA45C-8362-490B-8327-C68098FD4891}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {973CA45C-8362-490B-8327-C68098FD4891}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {973CA45C-8362-490B-8327-C68098FD4891}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {973CA45C-8362-490B-8327-C68098FD4891}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {973CA45C-8362-490B-8327-C68098FD4891}.Debug|x64.ActiveCfg = Debug|Any CPU
- {973CA45C-8362-490B-8327-C68098FD4891}.Debug|x86.ActiveCfg = Debug|Any CPU
- {973CA45C-8362-490B-8327-C68098FD4891}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {973CA45C-8362-490B-8327-C68098FD4891}.Release|Any CPU.Build.0 = Release|Any CPU
- {973CA45C-8362-490B-8327-C68098FD4891}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {973CA45C-8362-490B-8327-C68098FD4891}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {973CA45C-8362-490B-8327-C68098FD4891}.Release|Win32.ActiveCfg = Release|Any CPU
- {973CA45C-8362-490B-8327-C68098FD4891}.Release|x64.ActiveCfg = Release|Any CPU
- {973CA45C-8362-490B-8327-C68098FD4891}.Release|x86.ActiveCfg = Release|Any CPU
{67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Any CPU.Build.0 = Debug|Any CPU
{67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -350,6 +305,34 @@ Global
{FACAF749-3E28-46DD-B613-654FCD434959}.Release|Win32.ActiveCfg = Release|Any CPU
{FACAF749-3E28-46DD-B613-654FCD434959}.Release|x64.ActiveCfg = Release|Any CPU
{FACAF749-3E28-46DD-B613-654FCD434959}.Release|x86.ActiveCfg = Release|Any CPU
+ {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|Win32.ActiveCfg = Release|Any CPU
+ {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|x64.ActiveCfg = Release|Any CPU
+ {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|x86.ActiveCfg = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Release|Win32.ActiveCfg = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Release|x64.ActiveCfg = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE