diff options
| author | LukePulverenti <luke.pulverenti@gmail.com> | 2013-02-24 16:53:54 -0500 |
|---|---|---|
| committer | LukePulverenti <luke.pulverenti@gmail.com> | 2013-02-24 16:53:54 -0500 |
| commit | 8ce3e74e8112a94773df22827849bf274fc88198 (patch) | |
| tree | a4ce1edf34466be697e2e432609f6be80b6c6df6 /MediaBrowser.Common.Implementations | |
| parent | 6c86721f6de2acbe68e9419064ff21111ff3a223 (diff) | |
More DI
Diffstat (limited to 'MediaBrowser.Common.Implementations')
12 files changed, 1706 insertions, 0 deletions
diff --git a/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs b/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs new file mode 100644 index 000000000..93478b22c --- /dev/null +++ b/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs @@ -0,0 +1,304 @@ +using System; +using System.Configuration; +using System.IO; +using System.Reflection; + +namespace MediaBrowser.Common.Implementations +{ + /// <summary> + /// Provides a base class to hold common application paths used by both the Ui and Server. + /// This can be subclassed to add application-specific paths. + /// </summary> + public abstract class BaseApplicationPaths + { + /// <summary> + /// The _program data path + /// </summary> + private string _programDataPath; + /// <summary> + /// Gets the path to the program data folder + /// </summary> + /// <value>The program data path.</value> + public string ProgramDataPath + { + get + { + return _programDataPath ?? (_programDataPath = GetProgramDataPath()); + } + } + + /// <summary> + /// The _data directory + /// </summary> + private string _dataDirectory; + /// <summary> + /// Gets the folder path to the data directory + /// </summary> + /// <value>The data directory.</value> + public string DataPath + { + get + { + if (_dataDirectory == null) + { + _dataDirectory = Path.Combine(ProgramDataPath, "data"); + + if (!Directory.Exists(_dataDirectory)) + { + Directory.CreateDirectory(_dataDirectory); + } + } + + return _dataDirectory; + } + } + + /// <summary> + /// The _image cache path + /// </summary> + private string _imageCachePath; + /// <summary> + /// Gets the image cache path. + /// </summary> + /// <value>The image cache path.</value> + public string ImageCachePath + { + get + { + if (_imageCachePath == null) + { + _imageCachePath = Path.Combine(CachePath, "images"); + + if (!Directory.Exists(_imageCachePath)) + { + Directory.CreateDirectory(_imageCachePath); + } + } + + return _imageCachePath; + } + } + + /// <summary> + /// The _plugins path + /// </summary> + private string _pluginsPath; + /// <summary> + /// Gets the path to the plugin directory + /// </summary> + /// <value>The plugins path.</value> + public string PluginsPath + { + get + { + if (_pluginsPath == null) + { + _pluginsPath = Path.Combine(ProgramDataPath, "plugins"); + if (!Directory.Exists(_pluginsPath)) + { + Directory.CreateDirectory(_pluginsPath); + } + } + + return _pluginsPath; + } + } + + /// <summary> + /// The _plugin configurations path + /// </summary> + private string _pluginConfigurationsPath; + /// <summary> + /// Gets the path to the plugin configurations directory + /// </summary> + /// <value>The plugin configurations path.</value> + public string PluginConfigurationsPath + { + get + { + if (_pluginConfigurationsPath == null) + { + _pluginConfigurationsPath = Path.Combine(PluginsPath, "configurations"); + if (!Directory.Exists(_pluginConfigurationsPath)) + { + Directory.CreateDirectory(_pluginConfigurationsPath); + } + } + + return _pluginConfigurationsPath; + } + } + + private string _tempUpdatePath; + /// <summary> + /// Gets the path to where temporary update files will be stored + /// </summary> + /// <value>The plugin configurations path.</value> + public string TempUpdatePath + { + get + { + if (_tempUpdatePath == null) + { + _tempUpdatePath = Path.Combine(ProgramDataPath, "Updates"); + if (!Directory.Exists(_tempUpdatePath)) + { + Directory.CreateDirectory(_tempUpdatePath); + } + } + + return _tempUpdatePath; + } + } + + /// <summary> + /// The _log directory path + /// </summary> + private string _logDirectoryPath; + /// <summary> + /// Gets the path to the log directory + /// </summary> + /// <value>The log directory path.</value> + public string LogDirectoryPath + { + get + { + if (_logDirectoryPath == null) + { + _logDirectoryPath = Path.Combine(ProgramDataPath, "logs"); + if (!Directory.Exists(_logDirectoryPath)) + { + Directory.CreateDirectory(_logDirectoryPath); + } + } + return _logDirectoryPath; + } + } + + /// <summary> + /// The _configuration directory path + /// </summary> + private string _configurationDirectoryPath; + /// <summary> + /// Gets the path to the application configuration root directory + /// </summary> + /// <value>The configuration directory path.</value> + public string ConfigurationDirectoryPath + { + get + { + if (_configurationDirectoryPath == null) + { + _configurationDirectoryPath = Path.Combine(ProgramDataPath, "config"); + if (!Directory.Exists(_configurationDirectoryPath)) + { + Directory.CreateDirectory(_configurationDirectoryPath); + } + } + return _configurationDirectoryPath; + } + } + + /// <summary> + /// The _system configuration file path + /// </summary> + private string _systemConfigurationFilePath; + /// <summary> + /// Gets the path to the system configuration file + /// </summary> + /// <value>The system configuration file path.</value> + public string SystemConfigurationFilePath + { + get + { + return _systemConfigurationFilePath ?? (_systemConfigurationFilePath = Path.Combine(ConfigurationDirectoryPath, "system.xml")); + } + } + + /// <summary> + /// The _cache directory + /// </summary> + private string _cachePath; + /// <summary> + /// Gets the folder path to the cache directory + /// </summary> + /// <value>The cache directory.</value> + public string CachePath + { + get + { + if (_cachePath == null) + { + _cachePath = Path.Combine(ProgramDataPath, "cache"); + + if (!Directory.Exists(_cachePath)) + { + Directory.CreateDirectory(_cachePath); + } + } + + return _cachePath; + } + } + + /// <summary> + /// The _temp directory + /// </summary> + private string _tempDirectory; + /// <summary> + /// Gets the folder path to the temp directory within the cache folder + /// </summary> + /// <value>The temp directory.</value> + public string TempDirectory + { + get + { + if (_tempDirectory == null) + { + _tempDirectory = Path.Combine(CachePath, "temp"); + + if (!Directory.Exists(_tempDirectory)) + { + Directory.CreateDirectory(_tempDirectory); + } + } + + return _tempDirectory; + } + } + + /// <summary> + /// Gets the path to the application's ProgramDataFolder + /// </summary> + /// <returns>System.String.</returns> + public static string GetProgramDataPath() + { +#if DEBUG + string programDataPath = ConfigurationManager.AppSettings["DebugProgramDataPath"]; + +#else + string programDataPath = Path.Combine(ConfigurationManager.AppSettings["ReleaseProgramDataPath"], ConfigurationManager.AppSettings["ProgramDataFolderName"]); +#endif + + programDataPath = programDataPath.Replace("%CommonApplicationData%", Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); + + // If it's a relative path, e.g. "..\" + if (!Path.IsPathRooted(programDataPath)) + { + var path = Assembly.GetExecutingAssembly().Location; + path = Path.GetDirectoryName(path); + + programDataPath = Path.Combine(path, programDataPath); + + programDataPath = Path.GetFullPath(programDataPath); + } + + if (!Directory.Exists(programDataPath)) + { + Directory.CreateDirectory(programDataPath); + } + + return programDataPath; + } + } +} diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj new file mode 100644 index 000000000..d271db060 --- /dev/null +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -0,0 +1,87 @@ +<?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>{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <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> + <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> + <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="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.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" /> + <Import Project="$(SolutionDir)\.nuget\nuget.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project>
\ No newline at end of file diff --git a/MediaBrowser.Common.Implementations/Properties/AssemblyInfo.cs b/MediaBrowser.Common.Implementations/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f9c3e0bd1 --- /dev/null +++ b/MediaBrowser.Common.Implementations/Properties/AssemblyInfo.cs @@ -0,0 +1,31 @@ +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.Common.Implementations")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MediaBrowser.Common.Implementations")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("fc7d85c6-0fe7-4db6-8158-54f7b18f17cd")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs new file mode 100644 index 000000000..c6eca29d1 --- /dev/null +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs @@ -0,0 +1,322 @@ +using MediaBrowser.Common.Kernel; +using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.Tasks; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace MediaBrowser.Common.Implementations.ScheduledTasks +{ + /// <summary> + /// Class TaskManager + /// </summary> + public class TaskManager : ITaskManager + { + /// <summary> + /// Gets the list of Scheduled Tasks + /// </summary> + /// <value>The scheduled tasks.</value> + public IScheduledTask[] ScheduledTasks { get; private set; } + + /// <summary> + /// The _task queue + /// </summary> + private readonly List<Type> _taskQueue = new List<Type>(); + + /// <summary> + /// The _logger + /// </summary> + private readonly ILogger _logger; + + /// <summary> + /// The _application paths + /// </summary> + private readonly IApplicationPaths _applicationPaths; + + /// <summary> + /// The _json serializer + /// </summary> + private readonly IJsonSerializer _jsonSerializer; + + /// <summary> + /// Initializes a new instance of the <see cref="TaskManager" /> class. + /// </summary> + /// <param name="applicationPaths">The application paths.</param> + /// <param name="jsonSerializer">The json serializer.</param> + /// <param name="logger">The logger.</param> + /// <exception cref="System.ArgumentException">kernel</exception> + public TaskManager(IApplicationPaths applicationPaths, IJsonSerializer jsonSerializer, ILogger logger) + { + if (applicationPaths == null) + { + throw new ArgumentException("applicationPaths"); + } + if (jsonSerializer == null) + { + throw new ArgumentException("jsonSerializer"); + } + if (logger == null) + { + throw new ArgumentException("logger"); + } + + _applicationPaths = applicationPaths; + _jsonSerializer = jsonSerializer; + _logger = logger; + + ScheduledTasks = new IScheduledTask[] {}; + } + + /// <summary> + /// Cancels if running and queue. + /// </summary> + /// <typeparam name="T"></typeparam> + public void CancelIfRunningAndQueue<T>() + where T : IScheduledTask + { + ScheduledTasks.OfType<T>().First().CancelIfRunning(); + QueueScheduledTask<T>(); + } + + /// <summary> + /// Queues the scheduled task. + /// </summary> + /// <typeparam name="T"></typeparam> + public void QueueScheduledTask<T>() + where T : IScheduledTask + { + var scheduledTask = ScheduledTasks.OfType<T>().First(); + + QueueScheduledTask(scheduledTask); + } + + /// <summary> + /// Queues the scheduled task. + /// </summary> + /// <param name="task">The task.</param> + public void QueueScheduledTask(IScheduledTask task) + { + var type = task.GetType(); + + var scheduledTask = ScheduledTasks.First(t => t.GetType() == type); + + lock (_taskQueue) + { + // If it's idle just execute immediately + if (scheduledTask.State == TaskState.Idle) + { + scheduledTask.Execute(); + return; + } + + if (!_taskQueue.Contains(type)) + { + _logger.Info("Queueing task {0}", type.Name); + _taskQueue.Add(type); + } + else + { + _logger.Info("Task already queued: {0}", type.Name); + } + } + } + + /// <summary> + /// Called when [task completed]. + /// </summary> + /// <param name="task">The task.</param> + public void OnTaskCompleted(IScheduledTask task) + { + // Execute queued tasks + lock (_taskQueue) + { + var copy = _taskQueue.ToList(); + + foreach (var type in copy) + { + var scheduledTask = ScheduledTasks.First(t => t.GetType() == type); + + if (scheduledTask.State == TaskState.Idle) + { + scheduledTask.Execute(); + + _taskQueue.Remove(type); + } + } + } + } + + /// <summary> + /// Adds the tasks. + /// </summary> + /// <param name="tasks">The tasks.</param> + public void AddTasks(IEnumerable<IScheduledTask> tasks) + { + var myTasks = ScheduledTasks.ToList(); + + myTasks.AddRange(tasks); + + ScheduledTasks = myTasks.ToArray(); + } + + /// <summary> + /// The _scheduled tasks configuration directory + /// </summary> + private string _scheduledTasksConfigurationDirectory; + /// <summary> + /// Gets the scheduled tasks configuration directory. + /// </summary> + /// <value>The scheduled tasks configuration directory.</value> + private string ScheduledTasksConfigurationDirectory + { + get + { + if (_scheduledTasksConfigurationDirectory == null) + { + _scheduledTasksConfigurationDirectory = Path.Combine(_applicationPaths.ConfigurationDirectoryPath, "ScheduledTasks"); + + if (!Directory.Exists(_scheduledTasksConfigurationDirectory)) + { + Directory.CreateDirectory(_scheduledTasksConfigurationDirectory); + } + } + return _scheduledTasksConfigurationDirectory; + } + } + + /// <summary> + /// The _scheduled tasks data directory + /// </summary> + private string _scheduledTasksDataDirectory; + /// <summary> + /// Gets the scheduled tasks data directory. + /// </summary> + /// <value>The scheduled tasks data directory.</value> + private string ScheduledTasksDataDirectory + { + get + { + if (_scheduledTasksDataDirectory == null) + { + _scheduledTasksDataDirectory = Path.Combine(_applicationPaths.DataPath, "ScheduledTasks"); + + if (!Directory.Exists(_scheduledTasksDataDirectory)) + { + Directory.CreateDirectory(_scheduledTasksDataDirectory); + } + } + return _scheduledTasksDataDirectory; + } + } + + /// <summary> + /// Gets the history file path. + /// </summary> + /// <value>The history file path.</value> + private string GetHistoryFilePath(IScheduledTask task) + { + return Path.Combine(ScheduledTasksDataDirectory, task.Id + ".js"); + } + + /// <summary> + /// Gets the configuration file path. + /// </summary> + /// <param name="task">The task.</param> + /// <returns>System.String.</returns> + private string GetConfigurationFilePath(IScheduledTask task) + { + return Path.Combine(ScheduledTasksConfigurationDirectory, task.Id + ".js"); + } + + /// <summary> + /// Called when [task completed]. + /// </summary> + /// <param name="task">The task.</param> + /// <param name="startTime">The start time.</param> + /// <param name="endTime">The end time.</param> + /// <param name="status">The status.</param> + public void OnTaskCompleted(IScheduledTask task, DateTime startTime, DateTime endTime, TaskCompletionStatus status) + { + var elapsedTime = endTime - startTime; + + _logger.Info("{0} {1} after {2} minute(s) and {3} seconds", task.Name, status, Math.Truncate(elapsedTime.TotalMinutes), elapsedTime.Seconds); + + var result = new TaskResult + { + StartTimeUtc = startTime, + EndTimeUtc = endTime, + Status = status, + Name = task.Name, + Id = task.Id + }; + + _jsonSerializer.SerializeToFile(result, GetHistoryFilePath(task)); + + //task.LastExecutionResult = result; + } + + /// <summary> + /// Gets the last execution result. + /// </summary> + /// <param name="task">The task.</param> + /// <returns>TaskResult.</returns> + public TaskResult GetLastExecutionResult(IScheduledTask task) + { + return _jsonSerializer.DeserializeFromFile<TaskResult>(GetHistoryFilePath(task)); + } + + /// <summary> + /// Loads the triggers. + /// </summary> + /// <param name="task">The task.</param> + /// <returns>IEnumerable{BaseTaskTrigger}.</returns> + public IEnumerable<ITaskTrigger> LoadTriggers(IScheduledTask task) + { + try + { + return _jsonSerializer.DeserializeFromFile<IEnumerable<TaskTriggerInfo>>(GetConfigurationFilePath(task)) + .Select(ScheduledTaskHelpers.GetTrigger) + .ToList(); + } + catch (IOException) + { + // File doesn't exist. No biggie. Return defaults. + return task.GetDefaultTriggers(); + } + } + + /// <summary> + /// Saves the triggers. + /// </summary> + /// <param name="task">The task.</param> + /// <param name="triggers">The triggers.</param> + public void SaveTriggers(IScheduledTask task, IEnumerable<ITaskTrigger> triggers) + { + _jsonSerializer.SerializeToFile(triggers.Select(ScheduledTaskHelpers.GetTriggerInfo), GetConfigurationFilePath(task)); + } + + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// <summary> + /// Releases unmanaged and - optionally - managed resources. + /// </summary> + /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> + protected virtual void Dispose(bool dispose) + { + foreach (var task in ScheduledTasks) + { + task.Dispose(); + } + } + } +} diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs new file mode 100644 index 000000000..2ef056658 --- /dev/null +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs @@ -0,0 +1,119 @@ +using MediaBrowser.Common.Kernel; +using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Model.Logging; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks +{ + /// <summary> + /// Deletes old cache files + /// </summary> + public class DeleteCacheFileTask : BaseScheduledTask<IKernel> + { + /// <summary> + /// Initializes a new instance of the <see cref="DeleteCacheFileTask" /> class. + /// </summary> + /// <param name="kernel">The kernel.</param> + /// <param name="taskManager">The task manager.</param> + /// <param name="logger">The logger.</param> + public DeleteCacheFileTask(IKernel kernel, ITaskManager taskManager, ILogger logger) + : base(kernel, taskManager, logger) + { + } + + /// <summary> + /// Creates the triggers that define when the task will run + /// </summary> + /// <returns>IEnumerable{BaseTaskTrigger}.</returns> + public override IEnumerable<ITaskTrigger> GetDefaultTriggers() + { + var trigger = new DailyTrigger { TimeOfDay = TimeSpan.FromHours(2) }; //2am + + return new[] { trigger }; + } + + /// <summary> + /// Returns the task to be executed + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="progress">The progress.</param> + /// <returns>Task.</returns> + protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress) + { + return Task.Run(() => + { + var minDateModified = DateTime.UtcNow.AddMonths(-2); + + DeleteCacheFilesFromDirectory(cancellationToken, Kernel.ApplicationPaths.CachePath, minDateModified, progress); + }); + } + + + /// <summary> + /// Deletes the cache files from directory with a last write time less than a given date + /// </summary> + /// <param name="cancellationToken">The task cancellation token.</param> + /// <param name="directory">The directory.</param> + /// <param name="minDateModified">The min date modified.</param> + /// <param name="progress">The progress.</param> + private void DeleteCacheFilesFromDirectory(CancellationToken cancellationToken, string directory, DateTime minDateModified, IProgress<double> progress) + { + var filesToDelete = new DirectoryInfo(directory).EnumerateFileSystemInfos("*", SearchOption.AllDirectories) + .Where(f => !f.Attributes.HasFlag(FileAttributes.Directory) && f.LastWriteTimeUtc < minDateModified) + .ToList(); + + var index = 0; + + foreach (var file in filesToDelete) + { + double percent = index; + percent /= filesToDelete.Count; + + progress.Report(100 * percent); + + cancellationToken.ThrowIfCancellationRequested(); + + File.Delete(file.FullName); + + index++; + } + + progress.Report(100); + } + + /// <summary> + /// Gets the name of the task + /// </summary> + /// <value>The name.</value> + public override string Name + { + get { return "Cache file cleanup"; } + } + + /// <summary> + /// Gets the description. + /// </summary> + /// <value>The description.</value> + public override string Description + { + get { return "Deletes cache files no longer needed by the system"; } + } + + /// <summary> + /// Gets the category. + /// </summary> + /// <value>The category.</value> + public override string Category + { + get + { + return "Maintenance"; + } + } + } +} diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs new file mode 100644 index 000000000..dd00a7148 --- /dev/null +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs @@ -0,0 +1,107 @@ +using MediaBrowser.Common.Kernel; +using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Model.Logging; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks +{ + /// <summary> + /// Deletes old log files + /// </summary> + public class DeleteLogFileTask : BaseScheduledTask<IKernel> + { + /// <summary> + /// Initializes a new instance of the <see cref="DeleteLogFileTask" /> class. + /// </summary> + /// <param name="kernel">The kernel.</param> + /// <param name="taskManager">The task manager.</param> + /// <param name="logger">The logger.</param> + public DeleteLogFileTask(IKernel kernel, ITaskManager taskManager, ILogger logger) + : base(kernel, taskManager, logger) + { + } + + /// <summary> + /// Creates the triggers that define when the task will run + /// </summary> + /// <returns>IEnumerable{BaseTaskTrigger}.</returns> + public override IEnumerable<ITaskTrigger> GetDefaultTriggers() + { + var trigger = new DailyTrigger { TimeOfDay = TimeSpan.FromHours(2) }; //2am + + return new[] { trigger }; + } + + /// <summary> + /// Returns the task to be executed + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="progress">The progress.</param> + /// <returns>Task.</returns> + protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress) + { + return Task.Run(() => + { + // Delete log files more than n days old + var minDateModified = DateTime.UtcNow.AddDays(-(Kernel.Configuration.LogFileRetentionDays)); + + var filesToDelete = new DirectoryInfo(Kernel.ApplicationPaths.LogDirectoryPath).EnumerateFileSystemInfos("*", SearchOption.AllDirectories) + .Where(f => f.LastWriteTimeUtc < minDateModified) + .ToList(); + + var index = 0; + + foreach (var file in filesToDelete) + { + double percent = index; + percent /= filesToDelete.Count; + + progress.Report(100 * percent); + + cancellationToken.ThrowIfCancellationRequested(); + + File.Delete(file.FullName); + + index++; + } + + progress.Report(100); + }); + } + + /// <summary> + /// Gets the name of the task + /// </summary> + /// <value>The name.</value> + public override string Name + { + get { return "Log file cleanup"; } + } + + /// <summary> + /// Gets the description. + /// </summary> + /// <value>The description.</value> + public override string Description + { + get { return string.Format("Deletes log files that are more than {0} days old.", Kernel.Configuration.LogFileRetentionDays); } + } + + /// <summary> + /// Gets the category. + /// </summary> + /// <value>The category.</value> + public override string Category + { + get + { + return "Maintenance"; + } + } + } +} diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs new file mode 100644 index 000000000..79c633c76 --- /dev/null +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs @@ -0,0 +1,71 @@ +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.Implementations.ScheduledTasks.Tasks +{ + /// <summary> + /// Class ReloadLoggerFileTask + /// </summary> + public class ReloadLoggerFileTask : BaseScheduledTask<IKernel> + { + /// <summary> + /// Initializes a new instance of the <see cref="ReloadLoggerFileTask" /> class. + /// </summary> + /// <param name="kernel">The kernel.</param> + /// <param name="taskManager">The task manager.</param> + /// <param name="logger">The logger.</param> + public ReloadLoggerFileTask(IKernel kernel, ITaskManager taskManager, ILogger logger) + : base(kernel, taskManager, logger) + { + } + + /// <summary> + /// Gets the default triggers. + /// </summary> + /// <returns>IEnumerable{BaseTaskTrigger}.</returns> + public override IEnumerable<ITaskTrigger> GetDefaultTriggers() + { + var trigger = new DailyTrigger { TimeOfDay = TimeSpan.FromHours(0) }; //12am + + return new[] { trigger }; + } + + /// <summary> + /// Executes the internal. + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="progress">The progress.</param> + /// <returns>Task.</returns> + protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress) + { + cancellationToken.ThrowIfCancellationRequested(); + + progress.Report(0); + + return Task.Run(() => Kernel.ReloadLogger()); + } + + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + public override string Name + { + get { return "Start new log file"; } + } + + /// <summary> + /// Gets the description. + /// </summary> + /// <value>The description.</value> + public override string Description + { + get { return "Moves logging to a new file to help reduce log file sizes."; } + } + } +} diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs new file mode 100644 index 000000000..a101ad3dd --- /dev/null +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs @@ -0,0 +1,122 @@ +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.Implementations.ScheduledTasks.Tasks +{ + /// <summary> + /// Plugin Update Task + /// </summary> + public class SystemUpdateTask : BaseScheduledTask<IKernel> + { + /// <summary> + /// The _app host + /// </summary> + private readonly IApplicationHost _appHost; + + /// <summary> + /// Initializes a new instance of the <see cref="SystemUpdateTask" /> class. + /// </summary> + /// <param name="appHost">The app host.</param> + /// <param name="taskManager">The task manager.</param> + /// <param name="kernel">The kernel.</param> + /// <param name="logger">The logger.</param> + public SystemUpdateTask(IApplicationHost appHost, ITaskManager taskManager, IKernel kernel, ILogger logger) + : base(kernel, taskManager, logger) + { + _appHost = appHost; + } + + /// <summary> + /// Creates the triggers that define when the task will run + /// </summary> + /// <returns>IEnumerable{BaseTaskTrigger}.</returns> + public override IEnumerable<ITaskTrigger> GetDefaultTriggers() + { + return new ITaskTrigger[] { + + // 1am + new DailyTrigger { TimeOfDay = TimeSpan.FromHours(1) }, + + new IntervalTrigger { Interval = TimeSpan.FromHours(2)} + }; + } + + /// <summary> + /// Returns the task to be executed + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="progress">The progress.</param> + /// <returns>Task.</returns> + protected override async Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress) + { + if (!_appHost.CanSelfUpdate) return; + + EventHandler<double> innerProgressHandler = (sender, e) => progress.Report(e * .1); + + // Create a progress object for the update check + var innerProgress = new Progress<double>(); + innerProgress.ProgressChanged += innerProgressHandler; + + var updateInfo = await _appHost.CheckForApplicationUpdate(cancellationToken, innerProgress).ConfigureAwait(false); + + // Release the event handler + innerProgress.ProgressChanged -= innerProgressHandler; + + progress.Report(10); + + if (!updateInfo.IsUpdateAvailable) + { + progress.Report(100); + return; + } + + cancellationToken.ThrowIfCancellationRequested(); + + if (Kernel.Configuration.EnableAutoUpdate) + { + Logger.Info("Update Revision {0} available. Updating...", updateInfo.AvailableVersion); + + innerProgressHandler = (sender, e) => progress.Report((e * .9) + .1); + + innerProgress = new Progress<double>(); + innerProgress.ProgressChanged += innerProgressHandler; + + await _appHost.UpdateApplication(cancellationToken, innerProgress).ConfigureAwait(false); + + // Release the event handler + innerProgress.ProgressChanged -= innerProgressHandler; + + Kernel.OnApplicationUpdated(updateInfo.AvailableVersion); + } + else + { + Logger.Info("A new version of Media Browser is available."); + } + + progress.Report(100); + } + + /// <summary> + /// Gets the name of the task + /// </summary> + /// <value>The name.</value> + public override string Name + { + get { return "Check for application updates"; } + } + + /// <summary> + /// Gets the description. + /// </summary> + /// <value>The description.</value> + public override string Description + { + get { return "Downloads and installs application updates."; } + } + } +} diff --git a/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs new file mode 100644 index 000000000..bc8935a86 --- /dev/null +++ b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs @@ -0,0 +1,240 @@ +using MediaBrowser.Model.Serialization; +using System; +using System.IO; + +namespace MediaBrowser.Common.Implementations.Serialization +{ + /// <summary> + /// Provides a wrapper around third party json serialization. + /// </summary> + public class JsonSerializer : IJsonSerializer + { + public JsonSerializer() + { + Configure(); + } + + /// <summary> + /// Serializes to stream. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="obj">The obj.</param> + /// <param name="stream">The stream.</param> + /// <exception cref="System.ArgumentNullException">obj</exception> + public void SerializeToStream<T>(T obj, Stream stream) + where T : class + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + ServiceStack.Text.JsonSerializer.SerializeToStream(obj, obj.GetType(), stream); + } + + /// <summary> + /// Serializes to file. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="obj">The obj.</param> + /// <param name="file">The file.</param> + /// <exception cref="System.ArgumentNullException">obj</exception> + public void SerializeToFile<T>(T obj, string file) + where T : class + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + + if (string.IsNullOrEmpty(file)) + { + throw new ArgumentNullException("file"); + } + + using (Stream stream = File.Open(file, FileMode.Create)) + { + SerializeToStream(obj, stream); + } + } + + /// <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> + public object DeserializeFromFile(Type type, string file) + { + if (type == null) + { + throw new ArgumentNullException("type"); + } + + if (string.IsNullOrEmpty(file)) + { + throw new ArgumentNullException("file"); + } + + using (Stream stream = File.OpenRead(file)) + { + return ServiceStack.Text.JsonSerializer.DeserializeFromStream(type, stream); + } + } + + /// <summary> + /// Deserializes from file. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="file">The file.</param> + /// <returns>``0.</returns> + /// <exception cref="System.ArgumentNullException">file</exception> + public T DeserializeFromFile<T>(string file) + where T : class + { + if (string.IsNullOrEmpty(file)) + { + throw new ArgumentNullException("file"); + } + + using (Stream stream = File.OpenRead(file)) + { + return ServiceStack.Text.JsonSerializer.DeserializeFromStream<T>(stream); + } + } + + /// <summary> + /// Deserializes from stream. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="stream">The stream.</param> + /// <returns>``0.</returns> + /// <exception cref="System.ArgumentNullException">stream</exception> + public T DeserializeFromStream<T>(Stream stream) + { + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + return ServiceStack.Text.JsonSerializer.DeserializeFromStream<T>(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> + public T DeserializeFromString<T>(string text) + { + if (string.IsNullOrEmpty(text)) + { + throw new ArgumentNullException("text"); + } + + return ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(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> + public object DeserializeFromStream(Stream stream, Type type) + { + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + if (type == null) + { + throw new ArgumentNullException("type"); + } + + return ServiceStack.Text.JsonSerializer.DeserializeFromStream(type, stream); + } + + /// <summary> + /// Configures this instance. + /// </summary> + private void Configure() + { + ServiceStack.Text.JsConfig.DateHandler = ServiceStack.Text.JsonDateHandler.ISO8601; + ServiceStack.Text.JsConfig.ExcludeTypeInfo = true; + ServiceStack.Text.JsConfig.IncludeNullValues = false; + } + + /// <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> + public object DeserializeFromString(string json, Type type) + { + if (string.IsNullOrEmpty(json)) + { + throw new ArgumentNullException("json"); + } + + if (type == null) + { + throw new ArgumentNullException("type"); + } + + return ServiceStack.Text.JsonSerializer.DeserializeFromString(json, 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> + public string SerializeToString<T>(T obj) + where T : class + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + + return ServiceStack.Text.JsonSerializer.SerializeToString(obj, obj.GetType()); + } + + /// <summary> + /// Serializes to bytes. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="obj">The obj.</param> + /// <returns>System.Byte[][].</returns> + /// <exception cref="System.ArgumentNullException">obj</exception> + public byte[] SerializeToBytes<T>(T obj) + where T : class + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + + using (var stream = new MemoryStream()) + { + SerializeToStream(obj, stream); + return stream.ToArray(); + } + } + } +} diff --git a/MediaBrowser.Common.Implementations/Serialization/ProtobufSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/ProtobufSerializer.cs new file mode 100644 index 000000000..85325f3c1 --- /dev/null +++ b/MediaBrowser.Common.Implementations/Serialization/ProtobufSerializer.cs @@ -0,0 +1,158 @@ +using MediaBrowser.Model.Serialization; +using ProtoBuf; +using ProtoBuf.Meta; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace MediaBrowser.Common.Implementations.Serialization +{ + /// <summary> + /// Creates a compiled protobuf serializer based on a set of assemblies + /// </summary> + public class ProtobufSerializer : IProtobufSerializer + { + /// <summary> + /// Gets or sets the type model. + /// </summary> + /// <value>The type model.</value> + private TypeModel TypeModel { get; set; } + + /// <summary> + /// Serializes to stream. + /// </summary> + /// <param name="obj">The obj.</param> + /// <param name="stream">The stream.</param> + /// <exception cref="System.ArgumentNullException">obj</exception> + public void SerializeToStream(object obj, Stream stream) + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + TypeModel.Serialize(stream, obj); + } + + /// <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> + public object DeserializeFromStream(Stream stream, Type type) + { + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + return TypeModel.Deserialize(stream, null, type); + } + + /// <summary> + /// Deserializes from stream. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="stream">The stream.</param> + /// <returns>``0.</returns> + public T DeserializeFromStream<T>(Stream stream) + where T : class + { + return DeserializeFromStream(stream, typeof(T)) as T; + } + + /// <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> + public void SerializeToFile<T>(T obj, string file) + { + if (string.IsNullOrEmpty(file)) + { + throw new ArgumentNullException("file"); + } + + using (Stream stream = File.Open(file, FileMode.Create)) + { + SerializeToStream(obj, stream); + } + } + + /// <summary> + /// Deserializes from file. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="file">The file.</param> + /// <returns>``0.</returns> + /// <exception cref="System.ArgumentNullException">file</exception> + public T DeserializeFromFile<T>(string file) + where T : class + { + if (string.IsNullOrEmpty(file)) + { + throw new ArgumentNullException("file"); + } + + using (Stream stream = File.OpenRead(file)) + { + return DeserializeFromStream<T>(stream); + } + } + + /// <summary> + /// Serializes to bytes. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="obj">The obj.</param> + /// <returns>System.Byte[][].</returns> + /// <exception cref="System.ArgumentNullException">obj</exception> + public byte[] SerializeToBytes<T>(T obj) + where T : class + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + + using (var stream = new MemoryStream()) + { + SerializeToStream(obj, stream); + return stream.ToArray(); + } + } + + /// <summary> + /// Creates the specified assemblies. + /// </summary> + /// <returns>DynamicProtobufSerializer.</returns> + /// <exception cref="System.ArgumentNullException">assemblies</exception> + public static ProtobufSerializer Create(IEnumerable<Type> types) + { + if (types == null) + { + throw new ArgumentNullException("types"); + } + + var model = TypeModel.Create(); + var attributeType = typeof(ProtoContractAttribute); + + // Find all ProtoContracts in the current assembly + foreach (var type in types.Where(t => Attribute.IsDefined(t, attributeType))) + { + model.Add(type, true); + } + + return new ProtobufSerializer { TypeModel = model.Compile() }; + } + } +} diff --git a/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs new file mode 100644 index 000000000..d01199f6f --- /dev/null +++ b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs @@ -0,0 +1,140 @@ +using MediaBrowser.Model.Serialization; +using System; +using System.IO; +using System.Xml; + +namespace MediaBrowser.Common.Implementations.Serialization +{ + /// <summary> + /// Provides a wrapper around third party xml serialization. + /// </summary> + public class XmlSerializer : IXmlSerializer + { + /// <summary> + /// Serializes to writer. + /// </summary> + /// <param name="obj">The obj.</param> + /// <param name="writer">The writer.</param> + private void SerializeToWriter(object obj, XmlTextWriter writer) + { + writer.Formatting = Formatting.Indented; + var netSerializer = new System.Xml.Serialization.XmlSerializer(obj.GetType()); + netSerializer.Serialize(writer, obj); + } + + /// <summary> + /// Deserializes from stream. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="stream">The stream.</param> + /// <returns>``0.</returns> + public T DeserializeFromStream<T>(Stream stream) + { + using (var reader = new XmlTextReader(stream)) + { + var netSerializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); + + return (T)netSerializer.Deserialize(reader); + } + } + + /// <summary> + /// Deserializes from stream. + /// </summary> + /// <param name="type">The type.</param> + /// <param name="stream">The stream.</param> + /// <returns>System.Object.</returns> + public object DeserializeFromStream(Type type, Stream stream) + { + using (var reader = new XmlTextReader(stream)) + { + var netSerializer = new System.Xml.Serialization.XmlSerializer(type); + + return netSerializer.Deserialize(reader); + } + } + + /// <summary> + /// Serializes to stream. + /// </summary> + /// <param name="obj">The obj.</param> + /// <param name="stream">The stream.</param> + public void SerializeToStream(object obj, Stream stream) + { + using (var writer = new XmlTextWriter(stream, null)) + { + SerializeToWriter(obj, writer); + } + } + + /// <summary> + /// Deserializes from file. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="file">The file.</param> + /// <returns>``0.</returns> + public T DeserializeFromFile<T>(string file) + { + using (var stream = File.OpenRead(file)) + { + return DeserializeFromStream<T>(stream); + } + } + + /// <summary> + /// Serializes to file. + /// </summary> + /// <param name="obj">The obj.</param> + /// <param name="file">The file.</param> + public void SerializeToFile(object obj, string file) + { + using (var stream = new FileStream(file, FileMode.Create)) + { + SerializeToStream(obj, stream); + } + } + + /// <summary> + /// Deserializes from file. + /// </summary> + /// <param name="type">The type.</param> + /// <param name="file">The file.</param> + /// <returns>System.Object.</returns> + public object DeserializeFromFile(Type type, string file) + { + using (var stream = File.OpenRead(file)) + { + return DeserializeFromStream(type, stream); + } + } + + /// <summary> + /// Deserializes from bytes. + /// </summary> + /// <param name="type">The type.</param> + /// <param name="buffer">The buffer.</param> + /// <returns>System.Object.</returns> + public object DeserializeFromBytes(Type type, byte[] buffer) + { + using (var stream = new MemoryStream(buffer)) + { + return DeserializeFromStream(type, stream); + } + } + + /// <summary> + /// Serializes to bytes. + /// </summary> + /// <param name="obj">The obj.</param> + /// <returns>System.Byte[][].</returns> + public byte[] SerializeToBytes(object obj) + { + using (var stream = new MemoryStream()) + { + SerializeToStream(obj, stream); + + return stream.ToArray(); + } + } + } +} diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config new file mode 100644 index 000000000..14eb42cac --- /dev/null +++ b/MediaBrowser.Common.Implementations/packages.config @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="protobuf-net" version="2.0.0.621" targetFramework="net45" /> + <package id="ServiceStack.Text" version="3.9.37" targetFramework="net45" /> +</packages>
\ No newline at end of file |
