pull/702/head
LukePulverenti 11 years ago
parent 6c86721f6d
commit 8ce3e74e81

@ -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"));
}
}
}

@ -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;
@ -97,6 +98,26 @@ namespace MediaBrowser.Api
/// </summary>
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>
@ -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)
{

@ -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 />

@ -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
{
@ -119,6 +119,27 @@ namespace MediaBrowser.Api
/// </summary>
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>
@ -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);
}

@ -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);
}

@ -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; }
}
@ -48,6 +56,27 @@ namespace MediaBrowser.Api
/// </summary>
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>
@ -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);

@ -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);

@ -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
{
@ -135,6 +135,39 @@ namespace MediaBrowser.Api
/// </summary>
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>
@ -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;

@ -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>

@ -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
//

@ -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>

@ -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.

@ -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">

@ -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
//
//

@ -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();
}
}
}
}

@ -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

@ -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

@ -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

@ -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) },

@ -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)

@ -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() };
}
}
}

@ -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;
}
}
}

@ -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>

@ -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
@ -161,19 +159,6 @@ namespace MediaBrowser.Common.Kernel
/// <value>The application paths.</value>
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>
@ -204,46 +189,6 @@ namespace MediaBrowser.Common.Kernel
/// <value>The rest services.</value>
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.
@ -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>
@ -417,184 +355,14 @@ namespace MediaBrowser.Common.Kernel
OnLoggerLoaded();
}
/// <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();
}
}
@ -675,18 +438,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>
@ -699,17 +450,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>
@ -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;
}
}
}

@ -1,5 +1,6 @@
using MediaBrowser.Model.Updates;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
@ -32,6 +33,26 @@ namespace MediaBrowser.Common.Kernel
/// <value><c>true</c> if this instance can self update; otherwise, <c>false</c>.</value>
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>

@ -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; }
}
}

@ -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.
@ -32,12 +31,6 @@ namespace MediaBrowser.Common.Kernel
/// <value>The kernel context.</value>
KernelContext KernelContext { get; }
/// <summary>
/// Gets the protobuf serializer.
/// </summary>
/// <value>The protobuf serializer.</value>
DynamicProtobufSerializer ProtobufSerializer { get; }
/// <summary>
/// Inits this instance.
/// </summary>
@ -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);
}
}

@ -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
{
@ -35,6 +35,12 @@ namespace MediaBrowser.Common.Kernel
/// <value>The HTTP server.</value>
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>
@ -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(() =>
{

@ -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" />

@ -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;
//}
});
}
}

@ -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.

@ -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;
@ -38,14 +38,21 @@ namespace MediaBrowser.Common.Net
/// </summary>
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);
}

@ -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
@ -269,26 +269,38 @@ namespace MediaBrowser.Common.Plugins
/// <value>The logger.</value>
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)

@ -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.

@ -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)
{
@ -109,74 +108,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>
@ -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();
}
}
}

@ -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();
}
}
}
}

@ -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);
}
}
}

@ -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();
}
}

@ -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);
}
}

@ -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();
}
}

@ -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);
}
}
}

@ -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))
{

@ -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);
}
}
}
}

@ -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);
}
}
}
}

@ -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();
}
}
}

@ -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);
}
}
}

@ -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" />

@ -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.
@ -57,20 +57,32 @@ namespace MediaBrowser.Controller.Drawing
/// </summary>
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);
}
}
}

@ -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)

@ -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; }
}
}

@ -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;
@ -310,21 +319,10 @@ namespace MediaBrowser.Controller
BaseMetadataProvider.Logger = logger;
}
/// <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>();
}
});
}

@ -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" />

@ -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);
}
}

@ -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>

@ -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
{
@ -30,6 +30,27 @@ namespace MediaBrowser.Controller.Providers.Movies
/// </summary>
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>
@ -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;

@ -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>

@ -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>

@ -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
{
@ -23,6 +23,27 @@ namespace MediaBrowser.Controller.Providers.Movies
/// </summary>
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>
@ -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);

@ -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) }
};

@ -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) }
};

@ -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) },

@ -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) },

@ -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(),

@ -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
@ -108,15 +107,22 @@ namespace MediaBrowser.Controller.Updates
/// </summary>
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));

@ -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" />

@ -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;
}
}

@ -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;
}
}

@ -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);
}
}

@ -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">

@ -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;
@ -60,6 +61,12 @@ namespace MediaBrowser.Networking.Web
/// <value>The HTTP listener.</value>
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>
@ -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,

@ -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; }
}
}

@ -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);
}
}
}

@ -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; }
}
}

@ -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">

@ -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
//
//

@ -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

@ -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
@ -34,13 +35,37 @@ 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;

@ -2,7 +2,7 @@
using System.Data;
using System.Data.SQLite;
namespace MediaBrowser.Server.Sqlite
namespace MediaBrowser.Server.Implementations.Sqlite
{
/// <summary>
/// Class SQLiteExtensions

@ -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
@ -39,13 +39,38 @@ 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;

@ -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

@ -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
@ -33,13 +34,37 @@ 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;

@ -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
@ -34,13 +34,38 @@ 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;
}
}

@ -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
@ -22,18 +22,31 @@ namespace MediaBrowser.Server.WorldWeatherOnline
/// <value>The logger.</value>
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;
}

@ -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>
@ -135,12 +117,6 @@ namespace MediaBrowser.ServerApplication
get { return "MediaBrowser.Server.Uninstall.exe"; }
}
/// <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>
@ -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>
@ -391,17 +368,6 @@ namespace MediaBrowser.ServerApplication
Dispatcher.Invoke(Shutdown);
}
/// <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>
@ -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);
}
}
}

@ -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()
{
}
}
}

@ -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(() =>

@ -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;
@ -38,6 +39,11 @@ namespace MediaBrowser.ServerApplication
/// <value>The new item timer.</value>
private Timer NewItemTimer { get; set; }
/// <summary>
/// The _json serializer
/// </summary>
private readonly IJsonSerializer _jsonSerializer;
/// <summary>
/// The _logger
/// </summary>
@ -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>

@ -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>

@ -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>

@ -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,

@ -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

Loading…
Cancel
Save