aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Common.Implementations
diff options
context:
space:
mode:
authorLuke <luke.pulverenti@gmail.com>2016-10-30 03:29:27 -0400
committerGitHub <noreply@github.com>2016-10-30 03:29:27 -0400
commitd31b0f7be4b14e4ada999c97e675b856ad68352b (patch)
treea4619513efbb3be62a6204c996526df606cb62c5 /MediaBrowser.Common.Implementations
parentb19f75fcae017cb51f1e58eb2d54ca84620b6ee0 (diff)
parent3094cd7ff3e51578808ce1b6f56b141930c18004 (diff)
Merge pull request #2258 from MediaBrowser/dev
Dev
Diffstat (limited to 'MediaBrowser.Common.Implementations')
-rw-r--r--MediaBrowser.Common.Implementations/BaseApplicationHost.cs892
-rw-r--r--MediaBrowser.Common.Implementations/BaseApplicationPaths.cs178
-rw-r--r--MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs329
-rw-r--r--MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs59
-rw-r--r--MediaBrowser.Common.Implementations/Cryptography/CryptographyProvider.cs30
-rw-r--r--MediaBrowser.Common.Implementations/Devices/DeviceId.cs110
-rw-r--r--MediaBrowser.Common.Implementations/HttpClientManager/HttpClientInfo.cs16
-rw-r--r--MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs936
-rw-r--r--MediaBrowser.Common.Implementations/IO/IsoManager.cs75
-rw-r--r--MediaBrowser.Common.Implementations/IO/LnkShortcutHandler.cs399
-rw-r--r--MediaBrowser.Common.Implementations/IO/ManagedFileSystem.cs696
-rw-r--r--MediaBrowser.Common.Implementations/IO/WindowsFileSystem.cs14
-rw-r--r--MediaBrowser.Common.Implementations/Logging/LogHelper.cs97
-rw-r--r--MediaBrowser.Common.Implementations/Logging/NLogger.cs224
-rw-r--r--MediaBrowser.Common.Implementations/Logging/NlogManager.cs264
-rw-r--r--MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj138
-rw-r--r--MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs385
-rw-r--r--MediaBrowser.Common.Implementations/Properties/AssemblyInfo.cs30
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/DailyTrigger.cs91
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/IntervalTrigger.cs112
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs781
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/StartupTrigger.cs67
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/SystemEventTrigger.cs84
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs364
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs217
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs140
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerFileTask.cs113
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs116
-rw-r--r--MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs157
-rw-r--r--MediaBrowser.Common.Implementations/Security/MbAdmin.cs13
-rw-r--r--MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs337
-rw-r--r--MediaBrowser.Common.Implementations/Security/RegRecord.cs12
-rw-r--r--MediaBrowser.Common.Implementations/Security/SuppporterInfoResponse.cs14
-rw-r--r--MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs228
-rw-r--r--MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs130
-rw-r--r--MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs269
-rw-r--r--MediaBrowser.Common.Implementations/Updates/InstallationManager.cs686
-rw-r--r--MediaBrowser.Common.Implementations/packages.config6
38 files changed, 0 insertions, 8809 deletions
diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
deleted file mode 100644
index 3b14994190..0000000000
--- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
+++ /dev/null
@@ -1,892 +0,0 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Events;
-using MediaBrowser.Common.Implementations.Devices;
-using MediaBrowser.Common.Implementations.IO;
-using MediaBrowser.Common.Implementations.ScheduledTasks;
-using MediaBrowser.Common.Implementations.Security;
-using MediaBrowser.Common.Implementations.Serialization;
-using MediaBrowser.Common.Implementations.Updates;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Plugins;
-using MediaBrowser.Common.Progress;
-using MediaBrowser.Common.ScheduledTasks;
-using MediaBrowser.Common.Security;
-using MediaBrowser.Common.Updates;
-using MediaBrowser.Model.Events;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Updates;
-using ServiceStack;
-using SimpleInjector;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.Implementations.Cryptography;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.Cryptography;
-using MediaBrowser.Model.Tasks;
-
-namespace MediaBrowser.Common.Implementations
-{
- /// <summary>
- /// Class BaseApplicationHost
- /// </summary>
- /// <typeparam name="TApplicationPathsType">The type of the T application paths type.</typeparam>
- public abstract class BaseApplicationHost<TApplicationPathsType> : IApplicationHost, IDependencyContainer
- where TApplicationPathsType : class, IApplicationPaths
- {
- /// <summary>
- /// Occurs when [has pending restart changed].
- /// </summary>
- public event EventHandler HasPendingRestartChanged;
-
- /// <summary>
- /// Occurs when [application updated].
- /// </summary>
- public event EventHandler<GenericEventArgs<PackageVersionInfo>> ApplicationUpdated;
-
- /// <summary>
- /// Gets or sets a value indicating whether this instance has changes that require the entire application to restart.
- /// </summary>
- /// <value><c>true</c> if this instance has pending application restart; otherwise, <c>false</c>.</value>
- public bool HasPendingRestart { get; private set; }
-
- /// <summary>
- /// Gets or sets the logger.
- /// </summary>
- /// <value>The logger.</value>
- protected ILogger Logger { get; private set; }
-
- /// <summary>
- /// Gets or sets the plugins.
- /// </summary>
- /// <value>The plugins.</value>
- public IPlugin[] Plugins { get; protected set; }
-
- /// <summary>
- /// Gets or sets the log manager.
- /// </summary>
- /// <value>The log manager.</value>
- public ILogManager LogManager { get; protected set; }
-
- /// <summary>
- /// Gets the application paths.
- /// </summary>
- /// <value>The application paths.</value>
- protected TApplicationPathsType ApplicationPaths { get; private set; }
-
- /// <summary>
- /// The container
- /// </summary>
- protected readonly Container Container = new Container();
-
- /// <summary>
- /// The json serializer
- /// </summary>
- public IJsonSerializer JsonSerializer { get; private set; }
-
- /// <summary>
- /// The _XML serializer
- /// </summary>
- protected readonly IXmlSerializer XmlSerializer;
-
- /// <summary>
- /// Gets assemblies that failed to load
- /// </summary>
- /// <value>The failed assemblies.</value>
- public List<string> FailedAssemblies { get; protected set; }
-
- /// <summary>
- /// Gets all concrete types.
- /// </summary>
- /// <value>All concrete types.</value>
- public Type[] AllConcreteTypes { get; protected set; }
-
- /// <summary>
- /// The disposable parts
- /// </summary>
- protected readonly List<IDisposable> DisposableParts = new List<IDisposable>();
-
- /// <summary>
- /// Gets a value indicating whether this instance is first run.
- /// </summary>
- /// <value><c>true</c> if this instance is first run; otherwise, <c>false</c>.</value>
- public bool IsFirstRun { get; private set; }
-
- /// <summary>
- /// Gets the kernel.
- /// </summary>
- /// <value>The kernel.</value>
- protected ITaskManager TaskManager { get; private set; }
- /// <summary>
- /// Gets the security manager.
- /// </summary>
- /// <value>The security manager.</value>
- protected ISecurityManager SecurityManager { get; private set; }
- /// <summary>
- /// Gets the HTTP client.
- /// </summary>
- /// <value>The HTTP client.</value>
- public IHttpClient HttpClient { get; private set; }
- /// <summary>
- /// Gets the network manager.
- /// </summary>
- /// <value>The network manager.</value>
- protected INetworkManager NetworkManager { get; private set; }
-
- /// <summary>
- /// Gets the configuration manager.
- /// </summary>
- /// <value>The configuration manager.</value>
- protected IConfigurationManager ConfigurationManager { get; private set; }
-
- /// <summary>
- /// Gets or sets the installation manager.
- /// </summary>
- /// <value>The installation manager.</value>
- protected IInstallationManager InstallationManager { get; private set; }
-
- protected IFileSystem FileSystemManager { get; private set; }
-
- protected IIsoManager IsoManager { get; private set; }
-
- /// <summary>
- /// Gets the name.
- /// </summary>
- /// <value>The name.</value>
- public abstract string Name { get; }
-
- /// <summary>
- /// Gets a value indicating whether this instance is running as service.
- /// </summary>
- /// <value><c>true</c> if this instance is running as service; otherwise, <c>false</c>.</value>
- public abstract bool IsRunningAsService { get; }
-
- protected ICryptographyProvider CryptographyProvider = new CryptographyProvider();
-
- private DeviceId _deviceId;
- public string SystemId
- {
- get
- {
- if (_deviceId == null)
- {
- _deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId"), FileSystemManager);
- }
-
- return _deviceId.Value;
- }
- }
-
- public virtual string OperatingSystemDisplayName
- {
- get { return Environment.OSVersion.VersionString; }
- }
-
- public IMemoryStreamProvider MemoryStreamProvider { get; set; }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="BaseApplicationHost{TApplicationPathsType}"/> class.
- /// </summary>
- protected BaseApplicationHost(TApplicationPathsType applicationPaths,
- ILogManager logManager,
- IFileSystem fileSystem)
- {
- // hack alert, until common can target .net core
- BaseExtensions.CryptographyProvider = CryptographyProvider;
-
- XmlSerializer = new XmlSerializer(fileSystem, logManager.GetLogger("XmlSerializer"));
- FailedAssemblies = new List<string>();
-
- ApplicationPaths = applicationPaths;
- LogManager = logManager;
- FileSystemManager = fileSystem;
-
- ConfigurationManager = GetConfigurationManager();
-
- // Initialize this early in case the -v command line option is used
- Logger = LogManager.GetLogger("App");
- }
-
- /// <summary>
- /// Inits this instance.
- /// </summary>
- /// <returns>Task.</returns>
- public virtual async Task Init(IProgress<double> progress)
- {
- try
- {
- // https://github.com/ServiceStack/ServiceStack/blob/master/tests/ServiceStack.WebHost.IntegrationTests/Web.config#L4
- Licensing.RegisterLicense("1001-e1JlZjoxMDAxLE5hbWU6VGVzdCBCdXNpbmVzcyxUeXBlOkJ1c2luZXNzLEhhc2g6UHVNTVRPclhvT2ZIbjQ5MG5LZE1mUTd5RUMzQnBucTFEbTE3TDczVEF4QUNMT1FhNXJMOWkzVjFGL2ZkVTE3Q2pDNENqTkQyUktRWmhvUVBhYTBiekJGUUZ3ZE5aZHFDYm9hL3lydGlwUHI5K1JsaTBYbzNsUC85cjVJNHE5QVhldDN6QkE4aTlvdldrdTgyTk1relY2eis2dFFqTThYN2lmc0JveHgycFdjPSxFeHBpcnk6MjAxMy0wMS0wMX0=");
- }
- catch
- {
- // Failing under mono
- }
- progress.Report(1);
-
- JsonSerializer = CreateJsonSerializer();
-
- MemoryStreamProvider = CreateMemoryStreamProvider();
-
- OnLoggerLoaded(true);
- LogManager.LoggerLoaded += (s, e) => OnLoggerLoaded(false);
-
- IsFirstRun = !ConfigurationManager.CommonConfiguration.IsStartupWizardCompleted;
- progress.Report(2);
-
- LogManager.LogSeverity = ConfigurationManager.CommonConfiguration.EnableDebugLevelLogging
- ? LogSeverity.Debug
- : LogSeverity.Info;
-
- progress.Report(3);
-
- DiscoverTypes();
- progress.Report(14);
-
- SetHttpLimit();
- progress.Report(15);
-
- var innerProgress = new ActionableProgress<double>();
- innerProgress.RegisterAction(p => progress.Report(.8 * p + 15));
-
- await RegisterResources(innerProgress).ConfigureAwait(false);
-
- FindParts();
- progress.Report(95);
-
- await InstallIsoMounters(CancellationToken.None).ConfigureAwait(false);
-
- progress.Report(100);
- }
-
- protected abstract IMemoryStreamProvider CreateMemoryStreamProvider();
-
- protected virtual void OnLoggerLoaded(bool isFirstLoad)
- {
- Logger.Info("Application version: {0}", ApplicationVersion);
-
- if (!isFirstLoad)
- {
- LogEnvironmentInfo(Logger, ApplicationPaths, false);
- }
-
- // Put the app config in the log for troubleshooting purposes
- Logger.LogMultiline("Application configuration:", LogSeverity.Info, new StringBuilder(JsonSerializer.SerializeToString(ConfigurationManager.CommonConfiguration)));
-
- if (Plugins != null)
- {
- var pluginBuilder = new StringBuilder();
-
- foreach (var plugin in Plugins)
- {
- pluginBuilder.AppendLine(string.Format("{0} {1}", plugin.Name, plugin.Version));
- }
-
- Logger.LogMultiline("Plugins:", LogSeverity.Info, pluginBuilder);
- }
- }
-
- public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths, bool isStartup)
- {
- logger.LogMultiline("Emby", LogSeverity.Info, GetBaseExceptionMessage(appPaths));
- }
-
- protected static StringBuilder GetBaseExceptionMessage(IApplicationPaths appPaths)
- {
- var builder = new StringBuilder();
-
- builder.AppendLine(string.Format("Command line: {0}", string.Join(" ", Environment.GetCommandLineArgs())));
-
- builder.AppendLine(string.Format("Operating system: {0}", Environment.OSVersion));
- builder.AppendLine(string.Format("Processor count: {0}", Environment.ProcessorCount));
- builder.AppendLine(string.Format("64-Bit OS: {0}", Environment.Is64BitOperatingSystem));
- builder.AppendLine(string.Format("64-Bit Process: {0}", Environment.Is64BitProcess));
- builder.AppendLine(string.Format("Program data path: {0}", appPaths.ProgramDataPath));
-
- Type type = Type.GetType("Mono.Runtime");
- if (type != null)
- {
- MethodInfo displayName = type.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
- if (displayName != null)
- {
- builder.AppendLine("Mono: " + displayName.Invoke(null, null));
- }
- }
-
- builder.AppendLine(string.Format("Application Path: {0}", appPaths.ApplicationPath));
-
- return builder;
- }
-
- protected virtual IJsonSerializer CreateJsonSerializer()
- {
- return new JsonSerializer(FileSystemManager, LogManager.GetLogger("JsonSerializer"));
- }
-
- private void SetHttpLimit()
- {
- try
- {
- // Increase the max http request limit
- ServicePointManager.DefaultConnectionLimit = Math.Max(96, ServicePointManager.DefaultConnectionLimit);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error setting http limit", ex);
- }
- }
-
- /// <summary>
- /// Installs the iso mounters.
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
- private async Task InstallIsoMounters(CancellationToken cancellationToken)
- {
- var list = new List<IIsoMounter>();
-
- foreach (var isoMounter in GetExports<IIsoMounter>())
- {
- try
- {
- if (isoMounter.RequiresInstallation && !isoMounter.IsInstalled)
- {
- Logger.Info("Installing {0}", isoMounter.Name);
-
- await isoMounter.Install(cancellationToken).ConfigureAwait(false);
- }
-
- list.Add(isoMounter);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("{0} failed to load.", ex, isoMounter.Name);
- }
- }
-
- IsoManager.AddParts(list);
- }
-
- /// <summary>
- /// Runs the startup tasks.
- /// </summary>
- /// <returns>Task.</returns>
- public virtual Task RunStartupTasks()
- {
- Resolve<ITaskManager>().AddTasks(GetExports<IScheduledTask>(false));
-
- ConfigureAutorun();
-
- ConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated;
-
- return Task.FromResult(true);
- }
-
- /// <summary>
- /// Configures the autorun.
- /// </summary>
- private void ConfigureAutorun()
- {
- try
- {
- ConfigureAutoRunAtStartup(ConfigurationManager.CommonConfiguration.RunAtStartup);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error configuring autorun", ex);
- }
- }
-
- /// <summary>
- /// Gets the composable part assemblies.
- /// </summary>
- /// <returns>IEnumerable{Assembly}.</returns>
- protected abstract IEnumerable<Assembly> GetComposablePartAssemblies();
-
- /// <summary>
- /// Gets the configuration manager.
- /// </summary>
- /// <returns>IConfigurationManager.</returns>
- protected abstract IConfigurationManager GetConfigurationManager();
-
- /// <summary>
- /// Finds the parts.
- /// </summary>
- protected virtual void FindParts()
- {
- RegisterModules();
-
- ConfigurationManager.AddParts(GetExports<IConfigurationFactory>());
- Plugins = GetExports<IPlugin>().Select(LoadPlugin).Where(i => i != null).ToArray();
- }
-
- private IPlugin LoadPlugin(IPlugin plugin)
- {
- try
- {
- var assemblyPlugin = plugin as IPluginAssembly;
-
- if (assemblyPlugin != null)
- {
- var assembly = plugin.GetType().Assembly;
- var assemblyName = assembly.GetName();
-
- var attribute = (GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0];
- var assemblyId = new Guid(attribute.Value);
-
- var assemblyFileName = assemblyName.Name + ".dll";
- var assemblyFilePath = Path.Combine(ApplicationPaths.PluginsPath, assemblyFileName);
-
- assemblyPlugin.SetAttributes(assemblyFilePath, assemblyFileName, assemblyName.Version, assemblyId);
- }
-
- var isFirstRun = !File.Exists(plugin.ConfigurationFilePath);
-
- plugin.SetStartupInfo(isFirstRun, File.GetLastWriteTimeUtc, s => Directory.CreateDirectory(s));
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error loading plugin {0}", ex, plugin.GetType().FullName);
- return null;
- }
-
- return plugin;
- }
-
- /// <summary>
- /// Discovers the types.
- /// </summary>
- protected void DiscoverTypes()
- {
- FailedAssemblies.Clear();
-
- var assemblies = GetComposablePartAssemblies().ToList();
-
- foreach (var assembly in assemblies)
- {
- Logger.Info("Loading {0}", assembly.FullName);
- }
-
- AllConcreteTypes = assemblies
- .SelectMany(GetTypes)
- .Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType)
- .ToArray();
- }
-
- /// <summary>
- /// Registers resources that classes will depend on
- /// </summary>
- /// <returns>Task.</returns>
- protected virtual Task RegisterResources(IProgress<double> progress)
- {
- RegisterSingleInstance(ConfigurationManager);
- RegisterSingleInstance<IApplicationHost>(this);
-
- RegisterSingleInstance<IApplicationPaths>(ApplicationPaths);
-
- TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, LogManager.GetLogger("TaskManager"), FileSystemManager);
-
- RegisterSingleInstance(JsonSerializer);
- RegisterSingleInstance(XmlSerializer);
- RegisterSingleInstance(MemoryStreamProvider);
-
- RegisterSingleInstance(LogManager);
- RegisterSingleInstance(Logger);
-
- RegisterSingleInstance(TaskManager);
-
- RegisterSingleInstance(FileSystemManager);
-
- HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager, MemoryStreamProvider);
- RegisterSingleInstance(HttpClient);
-
- NetworkManager = CreateNetworkManager(LogManager.GetLogger("NetworkManager"));
- RegisterSingleInstance(NetworkManager);
-
- SecurityManager = new PluginSecurityManager(this, HttpClient, JsonSerializer, ApplicationPaths, LogManager);
- RegisterSingleInstance(SecurityManager);
-
- InstallationManager = new InstallationManager(LogManager.GetLogger("InstallationManager"), this, ApplicationPaths, HttpClient, JsonSerializer, SecurityManager, ConfigurationManager, FileSystemManager);
- RegisterSingleInstance(InstallationManager);
-
- IsoManager = new IsoManager();
- RegisterSingleInstance(IsoManager);
-
- return Task.FromResult(true);
- }
-
- private void RegisterModules()
- {
- var moduleTypes = GetExportTypes<IDependencyModule>();
-
- foreach (var type in moduleTypes)
- {
- try
- {
- var instance = Activator.CreateInstance(type) as IDependencyModule;
- if (instance != null)
- instance.BindDependencies(this);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error setting up dependency bindings for " + type.Name, ex);
- }
- }
- }
-
- /// <summary>
- /// Gets a list of types within an assembly
- /// This will handle situations that would normally throw an exception - such as a type within the assembly that depends on some other non-existant reference
- /// </summary>
- /// <param name="assembly">The assembly.</param>
- /// <returns>IEnumerable{Type}.</returns>
- /// <exception cref="System.ArgumentNullException">assembly</exception>
- protected IEnumerable<Type> GetTypes(Assembly assembly)
- {
- if (assembly == null)
- {
- throw new ArgumentNullException("assembly");
- }
-
- try
- {
- return assembly.GetTypes();
- }
- catch (ReflectionTypeLoadException ex)
- {
- if (ex.LoaderExceptions != null)
- {
- foreach (var loaderException in ex.LoaderExceptions)
- {
- Logger.Error("LoaderException: " + loaderException.Message);
- }
- }
-
- // If it fails we can still get a list of the Types it was able to resolve
- return ex.Types.Where(t => t != null);
- }
- }
-
- protected abstract INetworkManager CreateNetworkManager(ILogger logger);
-
- /// <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 (Exception ex)
- {
- Logger.ErrorException("Error creating {0}", ex, type.FullName);
-
- throw;
- }
- }
-
- /// <summary>
- /// Creates the instance safe.
- /// </summary>
- /// <param name="type">The type.</param>
- /// <returns>System.Object.</returns>
- protected object CreateInstanceSafe(Type type)
- {
- try
- {
- return Container.GetInstance(type);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error creating {0}", ex, type.FullName);
- // Don't blow up in release mode
- return null;
- }
- }
-
- void IDependencyContainer.RegisterSingleInstance<T>(T obj, bool manageLifetime)
- {
- RegisterSingleInstance(obj, manageLifetime);
- }
-
- /// <summary>
- /// Registers the specified obj.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="obj">The obj.</param>
- /// <param name="manageLifetime">if set to <c>true</c> [manage lifetime].</param>
- protected void RegisterSingleInstance<T>(T obj, bool manageLifetime = true)
- where T : class
- {
- Container.RegisterSingleton(obj);
-
- if (manageLifetime)
- {
- var disposable = obj as IDisposable;
-
- if (disposable != null)
- {
- DisposableParts.Add(disposable);
- }
- }
- }
-
- void IDependencyContainer.RegisterSingleInstance<T>(Func<T> func)
- {
- RegisterSingleInstance(func);
- }
-
- /// <summary>
- /// Registers the single instance.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="func">The func.</param>
- protected void RegisterSingleInstance<T>(Func<T> func)
- where T : class
- {
- Container.RegisterSingleton(func);
- }
-
- void IDependencyContainer.Register(Type typeInterface, Type typeImplementation)
- {
- Container.Register(typeInterface, typeImplementation);
- }
-
- /// <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>
- /// Loads the assembly.
- /// </summary>
- /// <param name="file">The file.</param>
- /// <returns>Assembly.</returns>
- protected Assembly LoadAssembly(string file)
- {
- try
- {
- return Assembly.Load(File.ReadAllBytes(file));
- }
- catch (Exception ex)
- {
- FailedAssemblies.Add(file);
- Logger.ErrorException("Error loading assembly {0}", ex, file);
- return null;
- }
- }
-
- /// <summary>
- /// Gets the export types.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <returns>IEnumerable{Type}.</returns>
- public IEnumerable<Type> GetExportTypes<T>()
- {
- var currentType = typeof(T);
-
- return AllConcreteTypes.AsParallel().Where(currentType.IsAssignableFrom);
- }
-
- /// <summary>
- /// Gets the exports.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="manageLiftime">if set to <c>true</c> [manage liftime].</param>
- /// <returns>IEnumerable{``0}.</returns>
- public IEnumerable<T> GetExports<T>(bool manageLiftime = true)
- {
- var parts = GetExportTypes<T>()
- .Select(CreateInstanceSafe)
- .Where(i => i != null)
- .Cast<T>()
- .ToList();
-
- if (manageLiftime)
- {
- lock (DisposableParts)
- {
- DisposableParts.AddRange(parts.OfType<IDisposable>());
- }
- }
-
- return parts;
- }
-
- /// <summary>
- /// Gets the application version.
- /// </summary>
- /// <value>The application version.</value>
- public abstract Version ApplicationVersion { get; }
-
- /// <summary>
- /// Handles the ConfigurationUpdated event of the ConfigurationManager control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
- /// <exception cref="System.NotImplementedException"></exception>
- protected virtual void OnConfigurationUpdated(object sender, EventArgs e)
- {
- ConfigureAutorun();
- }
-
- protected abstract void ConfigureAutoRunAtStartup(bool autorun);
-
- /// <summary>
- /// Removes the plugin.
- /// </summary>
- /// <param name="plugin">The plugin.</param>
- public void RemovePlugin(IPlugin plugin)
- {
- var list = Plugins.ToList();
- list.Remove(plugin);
- Plugins = list.ToArray();
- }
-
- /// <summary>
- /// Gets a value indicating whether this instance can self restart.
- /// </summary>
- /// <value><c>true</c> if this instance can self restart; otherwise, <c>false</c>.</value>
- public abstract bool CanSelfRestart { get; }
-
- /// <summary>
- /// Notifies that the kernel that a change has been made that requires a restart
- /// </summary>
- public void NotifyPendingRestart()
- {
- var changed = !HasPendingRestart;
-
- HasPendingRestart = true;
-
- if (changed)
- {
- EventHelper.QueueEventIfNotNull(HasPendingRestartChanged, this, EventArgs.Empty, Logger);
- }
- }
-
- /// <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)
- {
- if (dispose)
- {
- var type = GetType();
-
- Logger.Info("Disposing " + type.Name);
-
- var parts = DisposableParts.Distinct().Where(i => i.GetType() != type).ToList();
- DisposableParts.Clear();
-
- foreach (var part in parts)
- {
- Logger.Info("Disposing " + part.GetType().Name);
-
- try
- {
- part.Dispose();
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error disposing {0}", ex, part.GetType().Name);
- }
- }
- }
- }
-
- /// <summary>
- /// Restarts this instance.
- /// </summary>
- public abstract Task Restart();
-
- /// <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 abstract bool CanSelfUpdate { get; }
-
- /// <summary>
- /// Checks for update.
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="progress">The progress.</param>
- /// <returns>Task{CheckForUpdateResult}.</returns>
- public abstract Task<CheckForUpdateResult> CheckForApplicationUpdate(CancellationToken cancellationToken,
- IProgress<double> progress);
-
- /// <summary>
- /// Updates the application.
- /// </summary>
- /// <param name="package">The package that contains the update</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="progress">The progress.</param>
- /// <returns>Task.</returns>
- public abstract Task UpdateApplication(PackageVersionInfo package, CancellationToken cancellationToken,
- IProgress<double> progress);
-
- /// <summary>
- /// Shuts down.
- /// </summary>
- public abstract Task Shutdown();
-
- /// <summary>
- /// Called when [application updated].
- /// </summary>
- /// <param name="package">The package.</param>
- protected void OnApplicationUpdated(PackageVersionInfo package)
- {
- Logger.Info("Application has been updated to version {0}", package.versionStr);
-
- EventHelper.FireEventIfNotNull(ApplicationUpdated, this, new GenericEventArgs<PackageVersionInfo>
- {
- Argument = package
-
- }, Logger);
-
- NotifyPendingRestart();
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs b/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs
deleted file mode 100644
index 9ba2effd3a..0000000000
--- a/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs
+++ /dev/null
@@ -1,178 +0,0 @@
-using MediaBrowser.Common.Configuration;
-using System.IO;
-
-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 : IApplicationPaths
- {
- /// <summary>
- /// Initializes a new instance of the <see cref="BaseApplicationPaths"/> class.
- /// </summary>
- protected BaseApplicationPaths(string programDataPath, string applicationPath)
- {
- ProgramDataPath = programDataPath;
- ApplicationPath = applicationPath;
- }
-
- public string ApplicationPath { get; private set; }
- public string ProgramDataPath { get; private set; }
-
- /// <summary>
- /// Gets the path to the system folder
- /// </summary>
- public string ProgramSystemPath
- {
- get { return Path.GetDirectoryName(ApplicationPath); }
- }
-
- /// <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");
-
- Directory.CreateDirectory(_dataDirectory);
- }
-
- return _dataDirectory;
- }
- }
-
- /// <summary>
- /// Gets the image cache path.
- /// </summary>
- /// <value>The image cache path.</value>
- public string ImageCachePath
- {
- get
- {
- return Path.Combine(CachePath, "images");
- }
- }
-
- /// <summary>
- /// Gets the path to the plugin directory
- /// </summary>
- /// <value>The plugins path.</value>
- public string PluginsPath
- {
- get
- {
- return Path.Combine(ProgramDataPath, "plugins");
- }
- }
-
- /// <summary>
- /// Gets the path to the plugin configurations directory
- /// </summary>
- /// <value>The plugin configurations path.</value>
- public string PluginConfigurationsPath
- {
- get
- {
- return Path.Combine(PluginsPath, "configurations");
- }
- }
-
- /// <summary>
- /// Gets the path to where temporary update files will be stored
- /// </summary>
- /// <value>The plugin configurations path.</value>
- public string TempUpdatePath
- {
- get
- {
- return Path.Combine(ProgramDataPath, "updates");
- }
- }
-
- /// <summary>
- /// Gets the path to the log directory
- /// </summary>
- /// <value>The log directory path.</value>
- public string LogDirectoryPath
- {
- get
- {
- return Path.Combine(ProgramDataPath, "logs");
- }
- }
-
- /// <summary>
- /// Gets the path to the application configuration root directory
- /// </summary>
- /// <value>The configuration directory path.</value>
- public string ConfigurationDirectoryPath
- {
- get
- {
- return Path.Combine(ProgramDataPath, "config");
- }
- }
-
- /// <summary>
- /// Gets the path to the system configuration file
- /// </summary>
- /// <value>The system configuration file path.</value>
- public string SystemConfigurationFilePath
- {
- get
- {
- return 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 (string.IsNullOrEmpty(_cachePath))
- {
- _cachePath = Path.Combine(ProgramDataPath, "cache");
-
- Directory.CreateDirectory(_cachePath);
- }
-
- return _cachePath;
- }
- set
- {
- _cachePath = value;
- }
- }
-
- /// <summary>
- /// Gets the folder path to the temp directory within the cache folder
- /// </summary>
- /// <value>The temp directory.</value>
- public string TempDirectory
- {
- get
- {
- return Path.Combine(CachePath, "temp");
- }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs
deleted file mode 100644
index dd7a10b1ac..0000000000
--- a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs
+++ /dev/null
@@ -1,329 +0,0 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Events;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Serialization;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
-
-namespace MediaBrowser.Common.Implementations.Configuration
-{
- /// <summary>
- /// Class BaseConfigurationManager
- /// </summary>
- public abstract class BaseConfigurationManager : IConfigurationManager
- {
- /// <summary>
- /// Gets the type of the configuration.
- /// </summary>
- /// <value>The type of the configuration.</value>
- protected abstract Type ConfigurationType { get; }
-
- /// <summary>
- /// Occurs when [configuration updated].
- /// </summary>
- public event EventHandler<EventArgs> ConfigurationUpdated;
-
- /// <summary>
- /// Occurs when [configuration updating].
- /// </summary>
- public event EventHandler<ConfigurationUpdateEventArgs> NamedConfigurationUpdating;
-
- /// <summary>
- /// Occurs when [named configuration updated].
- /// </summary>
- public event EventHandler<ConfigurationUpdateEventArgs> NamedConfigurationUpdated;
-
- /// <summary>
- /// Gets the logger.
- /// </summary>
- /// <value>The logger.</value>
- protected ILogger Logger { get; private set; }
- /// <summary>
- /// Gets the XML serializer.
- /// </summary>
- /// <value>The XML serializer.</value>
- protected IXmlSerializer XmlSerializer { get; private set; }
-
- /// <summary>
- /// Gets or sets the application paths.
- /// </summary>
- /// <value>The application paths.</value>
- public IApplicationPaths CommonApplicationPaths { get; private set; }
- public readonly IFileSystem FileSystem;
-
- /// <summary>
- /// The _configuration loaded
- /// </summary>
- private bool _configurationLoaded;
- /// <summary>
- /// The _configuration sync lock
- /// </summary>
- private object _configurationSyncLock = new object();
- /// <summary>
- /// The _configuration
- /// </summary>
- private BaseApplicationConfiguration _configuration;
- /// <summary>
- /// Gets the system configuration
- /// </summary>
- /// <value>The configuration.</value>
- public BaseApplicationConfiguration CommonConfiguration
- {
- get
- {
- // Lazy load
- LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationLoaded, ref _configurationSyncLock, () => (BaseApplicationConfiguration)ConfigurationHelper.GetXmlConfiguration(ConfigurationType, CommonApplicationPaths.SystemConfigurationFilePath, XmlSerializer));
- return _configuration;
- }
- protected set
- {
- _configuration = value;
-
- _configurationLoaded = value != null;
- }
- }
-
- private ConfigurationStore[] _configurationStores = { };
- private IConfigurationFactory[] _configurationFactories = { };
-
- /// <summary>
- /// Initializes a new instance of the <see cref="BaseConfigurationManager" /> class.
- /// </summary>
- /// <param name="applicationPaths">The application paths.</param>
- /// <param name="logManager">The log manager.</param>
- /// <param name="xmlSerializer">The XML serializer.</param>
- protected BaseConfigurationManager(IApplicationPaths applicationPaths, ILogManager logManager, IXmlSerializer xmlSerializer, IFileSystem fileSystem)
- {
- CommonApplicationPaths = applicationPaths;
- XmlSerializer = xmlSerializer;
- FileSystem = fileSystem;
- Logger = logManager.GetLogger(GetType().Name);
-
- UpdateCachePath();
- }
-
- public virtual void AddParts(IEnumerable<IConfigurationFactory> factories)
- {
- _configurationFactories = factories.ToArray();
-
- _configurationStores = _configurationFactories
- .SelectMany(i => i.GetConfigurations())
- .ToArray();
- }
-
- /// <summary>
- /// Saves the configuration.
- /// </summary>
- public void SaveConfiguration()
- {
- Logger.Info("Saving system configuration");
- var path = CommonApplicationPaths.SystemConfigurationFilePath;
-
- Directory.CreateDirectory(Path.GetDirectoryName(path));
-
- lock (_configurationSyncLock)
- {
- XmlSerializer.SerializeToFile(CommonConfiguration, path);
- }
-
- OnConfigurationUpdated();
- }
-
- /// <summary>
- /// Called when [configuration updated].
- /// </summary>
- protected virtual void OnConfigurationUpdated()
- {
- UpdateCachePath();
-
- EventHelper.QueueEventIfNotNull(ConfigurationUpdated, this, EventArgs.Empty, Logger);
- }
-
- /// <summary>
- /// Replaces the configuration.
- /// </summary>
- /// <param name="newConfiguration">The new configuration.</param>
- /// <exception cref="System.ArgumentNullException">newConfiguration</exception>
- public virtual void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration)
- {
- if (newConfiguration == null)
- {
- throw new ArgumentNullException("newConfiguration");
- }
-
- ValidateCachePath(newConfiguration);
-
- CommonConfiguration = newConfiguration;
- SaveConfiguration();
- }
-
- /// <summary>
- /// Updates the items by name path.
- /// </summary>
- private void UpdateCachePath()
- {
- string cachePath;
-
- if (string.IsNullOrWhiteSpace(CommonConfiguration.CachePath))
- {
- cachePath = null;
- }
- else
- {
- cachePath = Path.Combine(CommonConfiguration.CachePath, "cache");
- }
-
- ((BaseApplicationPaths)CommonApplicationPaths).CachePath = cachePath;
- }
-
- /// <summary>
- /// Replaces the cache path.
- /// </summary>
- /// <param name="newConfig">The new configuration.</param>
- /// <exception cref="System.IO.DirectoryNotFoundException"></exception>
- private void ValidateCachePath(BaseApplicationConfiguration newConfig)
- {
- var newPath = newConfig.CachePath;
-
- if (!string.IsNullOrWhiteSpace(newPath)
- && !string.Equals(CommonConfiguration.CachePath ?? string.Empty, newPath))
- {
- // Validate
- if (!Directory.Exists(newPath))
- {
- throw new DirectoryNotFoundException(string.Format("{0} does not exist.", newPath));
- }
-
- EnsureWriteAccess(newPath);
- }
- }
-
- protected void EnsureWriteAccess(string path)
- {
- var file = Path.Combine(path, Guid.NewGuid().ToString());
-
- FileSystem.WriteAllText(file, string.Empty);
- FileSystem.DeleteFile(file);
- }
-
- private readonly ConcurrentDictionary<string, object> _configurations = new ConcurrentDictionary<string, object>();
-
- private string GetConfigurationFile(string key)
- {
- return Path.Combine(CommonApplicationPaths.ConfigurationDirectoryPath, key.ToLower() + ".xml");
- }
-
- public object GetConfiguration(string key)
- {
- return _configurations.GetOrAdd(key, k =>
- {
- var file = GetConfigurationFile(key);
-
- var configurationInfo = _configurationStores
- .FirstOrDefault(i => string.Equals(i.Key, key, StringComparison.OrdinalIgnoreCase));
-
- if (configurationInfo == null)
- {
- throw new ResourceNotFoundException("Configuration with key " + key + " not found.");
- }
-
- var configurationType = configurationInfo.ConfigurationType;
-
- lock (_configurationSyncLock)
- {
- return LoadConfiguration(file, configurationType);
- }
- });
- }
-
- private object LoadConfiguration(string path, Type configurationType)
- {
- try
- {
- return XmlSerializer.DeserializeFromFile(configurationType, path);
- }
- catch (FileNotFoundException)
- {
- return Activator.CreateInstance(configurationType);
- }
- catch (DirectoryNotFoundException)
- {
- return Activator.CreateInstance(configurationType);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error loading configuration file: {0}", ex, path);
-
- return Activator.CreateInstance(configurationType);
- }
- }
-
- public void SaveConfiguration(string key, object configuration)
- {
- var configurationStore = GetConfigurationStore(key);
- var configurationType = configurationStore.ConfigurationType;
-
- if (configuration.GetType() != configurationType)
- {
- throw new ArgumentException("Expected configuration type is " + configurationType.Name);
- }
-
- var validatingStore = configurationStore as IValidatingConfiguration;
- if (validatingStore != null)
- {
- var currentConfiguration = GetConfiguration(key);
-
- validatingStore.Validate(currentConfiguration, configuration);
- }
-
- EventHelper.FireEventIfNotNull(NamedConfigurationUpdating, this, new ConfigurationUpdateEventArgs
- {
- Key = key,
- NewConfiguration = configuration
-
- }, Logger);
-
- _configurations.AddOrUpdate(key, configuration, (k, v) => configuration);
-
- var path = GetConfigurationFile(key);
- Directory.CreateDirectory(Path.GetDirectoryName(path));
-
- lock (_configurationSyncLock)
- {
- XmlSerializer.SerializeToFile(configuration, path);
- }
-
- OnNamedConfigurationUpdated(key, configuration);
- }
-
- protected virtual void OnNamedConfigurationUpdated(string key, object configuration)
- {
- EventHelper.FireEventIfNotNull(NamedConfigurationUpdated, this, new ConfigurationUpdateEventArgs
- {
- Key = key,
- NewConfiguration = configuration
-
- }, Logger);
- }
-
- public Type GetConfigurationType(string key)
- {
- return GetConfigurationStore(key)
- .ConfigurationType;
- }
-
- private ConfigurationStore GetConfigurationStore(string key)
- {
- return _configurationStores
- .First(i => string.Equals(i.Key, key, StringComparison.OrdinalIgnoreCase));
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs b/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs
deleted file mode 100644
index 419b85fa73..0000000000
--- a/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using MediaBrowser.Model.Serialization;
-using System;
-using System.IO;
-using System.Linq;
-
-namespace MediaBrowser.Common.Implementations.Configuration
-{
- /// <summary>
- /// Class ConfigurationHelper
- /// </summary>
- public static class ConfigurationHelper
- {
- /// <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="xmlSerializer">The XML serializer.</param>
- /// <returns>System.Object.</returns>
- public static object GetXmlConfiguration(Type type, string path, IXmlSerializer xmlSerializer)
- {
- 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 (Exception)
- {
- configuration = Activator.CreateInstance(type);
- }
-
- using (var stream = new MemoryStream())
- {
- xmlSerializer.SerializeToStream(configuration, stream);
-
- // Take the object we just got and serialize it back to bytes
- var newBytes = stream.ToArray();
-
- // If the file didn't exist before, or if something has changed, re-save
- if (buffer == null || !buffer.SequenceEqual(newBytes))
- {
- Directory.CreateDirectory(Path.GetDirectoryName(path));
-
- // Save it after load in case we got new items
- File.WriteAllBytes(path, newBytes);
- }
-
- return configuration;
- }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Cryptography/CryptographyProvider.cs b/MediaBrowser.Common.Implementations/Cryptography/CryptographyProvider.cs
deleted file mode 100644
index 67dbd76d24..0000000000
--- a/MediaBrowser.Common.Implementations/Cryptography/CryptographyProvider.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System;
-using System.IO;
-using System.Security.Cryptography;
-using System.Text;
-using MediaBrowser.Model.Cryptography;
-
-namespace MediaBrowser.Common.Implementations.Cryptography
-{
- public class CryptographyProvider : ICryptographyProvider
- {
- public Guid GetMD5(string str)
- {
- return new Guid(GetMD5Bytes(str));
- }
- public byte[] GetMD5Bytes(string str)
- {
- using (var provider = MD5.Create())
- {
- return provider.ComputeHash(Encoding.Unicode.GetBytes(str));
- }
- }
- public byte[] GetMD5Bytes(Stream str)
- {
- using (var provider = MD5.Create())
- {
- return provider.ComputeHash(str);
- }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Devices/DeviceId.cs b/MediaBrowser.Common.Implementations/Devices/DeviceId.cs
deleted file mode 100644
index a43697c7be..0000000000
--- a/MediaBrowser.Common.Implementations/Devices/DeviceId.cs
+++ /dev/null
@@ -1,110 +0,0 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Model.Logging;
-using System;
-using System.IO;
-using System.Text;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.IO;
-
-namespace MediaBrowser.Common.Implementations.Devices
-{
- public class DeviceId
- {
- private readonly IApplicationPaths _appPaths;
- private readonly ILogger _logger;
- private readonly IFileSystem _fileSystem;
-
- private readonly object _syncLock = new object();
-
- private string CachePath
- {
- get { return Path.Combine(_appPaths.DataPath, "device.txt"); }
- }
-
- private string GetCachedId()
- {
- try
- {
- lock (_syncLock)
- {
- var value = File.ReadAllText(CachePath, Encoding.UTF8);
-
- Guid guid;
- if (Guid.TryParse(value, out guid))
- {
- return value;
- }
-
- _logger.Error("Invalid value found in device id file");
- }
- }
- catch (DirectoryNotFoundException)
- {
- }
- catch (FileNotFoundException)
- {
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error reading file", ex);
- }
-
- return null;
- }
-
- private void SaveId(string id)
- {
- try
- {
- var path = CachePath;
-
- _fileSystem.CreateDirectory(Path.GetDirectoryName(path));
-
- lock (_syncLock)
- {
- _fileSystem.WriteAllText(path, id, Encoding.UTF8);
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error writing to file", ex);
- }
- }
-
- private string GetNewId()
- {
- return Guid.NewGuid().ToString("N");
- }
-
- private string GetDeviceId()
- {
- var id = GetCachedId();
-
- if (string.IsNullOrWhiteSpace(id))
- {
- id = GetNewId();
- SaveId(id);
- }
-
- return id;
- }
-
- private string _id;
-
- public DeviceId(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem)
- {
- if (fileSystem == null) {
- throw new ArgumentNullException ("fileSystem");
- }
-
- _appPaths = appPaths;
- _logger = logger;
- _fileSystem = fileSystem;
- }
-
- public string Value
- {
- get { return _id ?? (_id = GetDeviceId()); }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientInfo.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientInfo.cs
deleted file mode 100644
index 8af6ef6c6e..0000000000
--- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientInfo.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-
-namespace MediaBrowser.Common.Implementations.HttpClientManager
-{
- /// <summary>
- /// Class HttpClientInfo
- /// </summary>
- public class HttpClientInfo
- {
- /// <summary>
- /// Gets or sets the last timeout.
- /// </summary>
- /// <value>The last timeout.</value>
- public DateTime LastTimeout { get; set; }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
deleted file mode 100644
index b18178ead2..0000000000
--- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
+++ /dev/null
@@ -1,936 +0,0 @@
-using System.Net.Sockets;
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Net;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Net.Cache;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.IO;
-
-namespace MediaBrowser.Common.Implementations.HttpClientManager
-{
- /// <summary>
- /// Class HttpClientManager
- /// </summary>
- public class HttpClientManager : IHttpClient
- {
- /// <summary>
- /// When one request to a host times out, we'll ban all other requests for this period of time, to prevent scans from stalling
- /// </summary>
- private const int TimeoutSeconds = 30;
-
- /// <summary>
- /// The _logger
- /// </summary>
- private readonly ILogger _logger;
-
- /// <summary>
- /// The _app paths
- /// </summary>
- private readonly IApplicationPaths _appPaths;
-
- private readonly IFileSystem _fileSystem;
- private readonly IMemoryStreamProvider _memoryStreamProvider;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="HttpClientManager" /> class.
- /// </summary>
- /// <param name="appPaths">The app paths.</param>
- /// <param name="logger">The logger.</param>
- /// <param name="fileSystem">The file system.</param>
- /// <exception cref="System.ArgumentNullException">appPaths
- /// or
- /// logger</exception>
- public HttpClientManager(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem, IMemoryStreamProvider memoryStreamProvider)
- {
- if (appPaths == null)
- {
- throw new ArgumentNullException("appPaths");
- }
- if (logger == null)
- {
- throw new ArgumentNullException("logger");
- }
-
- _logger = logger;
- _fileSystem = fileSystem;
- _memoryStreamProvider = memoryStreamProvider;
- _appPaths = appPaths;
-
- // http://stackoverflow.com/questions/566437/http-post-returns-the-error-417-expectation-failed-c
- ServicePointManager.Expect100Continue = false;
-
- // Trakt requests sometimes fail without this
- ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls;
- }
-
- /// <summary>
- /// Holds a dictionary of http clients by host. Use GetHttpClient(host) to retrieve or create a client for web requests.
- /// DON'T dispose it after use.
- /// </summary>
- /// <value>The HTTP clients.</value>
- private readonly ConcurrentDictionary<string, HttpClientInfo> _httpClients = new ConcurrentDictionary<string, HttpClientInfo>();
-
- /// <summary>
- /// Gets
- /// </summary>
- /// <param name="host">The host.</param>
- /// <param name="enableHttpCompression">if set to <c>true</c> [enable HTTP compression].</param>
- /// <returns>HttpClient.</returns>
- /// <exception cref="System.ArgumentNullException">host</exception>
- private HttpClientInfo GetHttpClient(string host, bool enableHttpCompression)
- {
- if (string.IsNullOrEmpty(host))
- {
- throw new ArgumentNullException("host");
- }
-
- HttpClientInfo client;
-
- var key = host + enableHttpCompression;
-
- if (!_httpClients.TryGetValue(key, out client))
- {
- client = new HttpClientInfo();
-
- _httpClients.TryAdd(key, client);
- }
-
- return client;
- }
-
- private WebRequest CreateWebRequest(string url)
- {
- try
- {
- return WebRequest.Create(url);
- }
- catch (NotSupportedException)
- {
- //Webrequest creation does fail on MONO randomly when using WebRequest.Create
- //the issue occurs in the GetCreator method here: http://www.oschina.net/code/explore/mono-2.8.1/mcs/class/System/System.Net/WebRequest.cs
-
- var type = Type.GetType("System.Net.HttpRequestCreator, System, Version=4.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089");
- var creator = Activator.CreateInstance(type, nonPublic: true) as IWebRequestCreate;
- return creator.Create(new Uri(url)) as HttpWebRequest;
- }
- }
-
- private void AddIpv4Option(HttpWebRequest request, HttpRequestOptions options)
- {
- request.ServicePoint.BindIPEndPointDelegate = (servicePount, remoteEndPoint, retryCount) =>
- {
- if (remoteEndPoint.AddressFamily == AddressFamily.InterNetwork)
- {
- return new IPEndPoint(IPAddress.Any, 0);
- }
- throw new InvalidOperationException("no IPv4 address");
- };
- }
-
- private WebRequest GetRequest(HttpRequestOptions options, string method)
- {
- var url = options.Url;
-
- var uriAddress = new Uri(url);
- var userInfo = uriAddress.UserInfo;
- if (!string.IsNullOrWhiteSpace(userInfo))
- {
- _logger.Info("Found userInfo in url: {0} ... url: {1}", userInfo, url);
- url = url.Replace(userInfo + "@", string.Empty);
- }
-
- var request = CreateWebRequest(url);
- var httpWebRequest = request as HttpWebRequest;
-
- if (httpWebRequest != null)
- {
- if (options.PreferIpv4)
- {
- AddIpv4Option(httpWebRequest, options);
- }
-
- AddRequestHeaders(httpWebRequest, options);
-
- httpWebRequest.AutomaticDecompression = options.EnableHttpCompression ?
- (options.DecompressionMethod ?? DecompressionMethods.Deflate) :
- DecompressionMethods.None;
- }
-
- request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
-
- if (httpWebRequest != null)
- {
- if (options.EnableKeepAlive)
- {
- httpWebRequest.KeepAlive = true;
- }
- }
-
- request.Method = method;
- request.Timeout = options.TimeoutMs;
-
- if (httpWebRequest != null)
- {
- if (!string.IsNullOrEmpty(options.Host))
- {
- httpWebRequest.Host = options.Host;
- }
-
- if (!string.IsNullOrEmpty(options.Referer))
- {
- httpWebRequest.Referer = options.Referer;
- }
- }
-
- if (!string.IsNullOrWhiteSpace(userInfo))
- {
- var parts = userInfo.Split(':');
- if (parts.Length == 2)
- {
- request.Credentials = GetCredential(url, parts[0], parts[1]);
- request.PreAuthenticate = true;
- }
- }
-
- return request;
- }
-
- private CredentialCache GetCredential(string url, string username, string password)
- {
- //ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
- CredentialCache credentialCache = new CredentialCache();
- credentialCache.Add(new Uri(url), "Basic", new NetworkCredential(username, password));
- return credentialCache;
- }
-
- private void AddRequestHeaders(HttpWebRequest request, HttpRequestOptions options)
- {
- foreach (var header in options.RequestHeaders.ToList())
- {
- if (string.Equals(header.Key, "Accept", StringComparison.OrdinalIgnoreCase))
- {
- request.Accept = header.Value;
- }
- else if (string.Equals(header.Key, "User-Agent", StringComparison.OrdinalIgnoreCase))
- {
- request.UserAgent = header.Value;
- }
- else
- {
- request.Headers.Set(header.Key, header.Value);
- }
- }
- }
-
- /// <summary>
- /// Gets the response internal.
- /// </summary>
- /// <param name="options">The options.</param>
- /// <returns>Task{HttpResponseInfo}.</returns>
- public Task<HttpResponseInfo> GetResponse(HttpRequestOptions options)
- {
- return SendAsync(options, "GET");
- }
-
- /// <summary>
- /// Performs a GET request and returns the resulting stream
- /// </summary>
- /// <param name="options">The options.</param>
- /// <returns>Task{Stream}.</returns>
- public async Task<Stream> Get(HttpRequestOptions options)
- {
- var response = await GetResponse(options).ConfigureAwait(false);
-
- return response.Content;
- }
-
- /// <summary>
- /// Performs a GET request and returns the resulting stream
- /// </summary>
- /// <param name="url">The URL.</param>
- /// <param name="resourcePool">The resource pool.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task{Stream}.</returns>
- public Task<Stream> Get(string url, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
- {
- return Get(new HttpRequestOptions
- {
- Url = url,
- ResourcePool = resourcePool,
- CancellationToken = cancellationToken,
- BufferContent = resourcePool != null
- });
- }
-
- /// <summary>
- /// Gets the specified URL.
- /// </summary>
- /// <param name="url">The URL.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task{Stream}.</returns>
- public Task<Stream> Get(string url, CancellationToken cancellationToken)
- {
- return Get(url, null, cancellationToken);
- }
-
- /// <summary>
- /// send as an asynchronous operation.
- /// </summary>
- /// <param name="options">The options.</param>
- /// <param name="httpMethod">The HTTP method.</param>
- /// <returns>Task{HttpResponseInfo}.</returns>
- /// <exception cref="HttpException">
- /// </exception>
- public async Task<HttpResponseInfo> SendAsync(HttpRequestOptions options, string httpMethod)
- {
- if (options.CacheMode == CacheMode.None)
- {
- return await SendAsyncInternal(options, httpMethod).ConfigureAwait(false);
- }
-
- var url = options.Url;
- var urlHash = url.ToLower().GetMD5().ToString("N");
-
- var responseCachePath = Path.Combine(_appPaths.CachePath, "httpclient", urlHash);
-
- var response = await GetCachedResponse(responseCachePath, options.CacheLength, url).ConfigureAwait(false);
- if (response != null)
- {
- return response;
- }
-
- response = await SendAsyncInternal(options, httpMethod).ConfigureAwait(false);
-
- if (response.StatusCode == HttpStatusCode.OK)
- {
- await CacheResponse(response, responseCachePath).ConfigureAwait(false);
- }
-
- return response;
- }
-
- private async Task<HttpResponseInfo> GetCachedResponse(string responseCachePath, TimeSpan cacheLength, string url)
- {
- _logger.Info("Checking for cache file {0}", responseCachePath);
-
- try
- {
- if (_fileSystem.GetLastWriteTimeUtc(responseCachePath).Add(cacheLength) > DateTime.UtcNow)
- {
- using (var stream = _fileSystem.GetFileStream(responseCachePath, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read, true))
- {
- var memoryStream = _memoryStreamProvider.CreateNew();
-
- await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
- memoryStream.Position = 0;
-
- return new HttpResponseInfo
- {
- ResponseUrl = url,
- Content = memoryStream,
- StatusCode = HttpStatusCode.OK,
- ContentLength = memoryStream.Length
- };
- }
- }
- }
- catch (FileNotFoundException)
- {
-
- }
- catch (DirectoryNotFoundException)
- {
-
- }
-
- return null;
- }
-
- private async Task CacheResponse(HttpResponseInfo response, string responseCachePath)
- {
- _fileSystem.CreateDirectory(Path.GetDirectoryName(responseCachePath));
-
- using (var responseStream = response.Content)
- {
- var memoryStream = _memoryStreamProvider.CreateNew();
- await responseStream.CopyToAsync(memoryStream).ConfigureAwait(false);
- memoryStream.Position = 0;
-
- using (var fileStream = _fileSystem.GetFileStream(responseCachePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None, true))
- {
- await memoryStream.CopyToAsync(fileStream).ConfigureAwait(false);
-
- memoryStream.Position = 0;
- response.Content = memoryStream;
- }
- }
- }
-
- private async Task<HttpResponseInfo> SendAsyncInternal(HttpRequestOptions options, string httpMethod)
- {
- ValidateParams(options);
-
- options.CancellationToken.ThrowIfCancellationRequested();
-
- var client = GetHttpClient(GetHostFromUrl(options.Url), options.EnableHttpCompression);
-
- if ((DateTime.UtcNow - client.LastTimeout).TotalSeconds < TimeoutSeconds)
- {
- throw new HttpException(string.Format("Cancelling connection to {0} due to a previous timeout.", options.Url))
- {
- IsTimedOut = true
- };
- }
-
- var httpWebRequest = GetRequest(options, httpMethod);
-
- if (options.RequestContentBytes != null ||
- !string.IsNullOrEmpty(options.RequestContent) ||
- string.Equals(httpMethod, "post", StringComparison.OrdinalIgnoreCase))
- {
- var bytes = options.RequestContentBytes ??
- Encoding.UTF8.GetBytes(options.RequestContent ?? string.Empty);
-
- httpWebRequest.ContentType = options.RequestContentType ?? "application/x-www-form-urlencoded";
-
- httpWebRequest.ContentLength = bytes.Length;
- httpWebRequest.GetRequestStream().Write(bytes, 0, bytes.Length);
- }
-
- if (options.ResourcePool != null)
- {
- await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false);
- }
-
- if ((DateTime.UtcNow - client.LastTimeout).TotalSeconds < TimeoutSeconds)
- {
- if (options.ResourcePool != null)
- {
- options.ResourcePool.Release();
- }
-
- throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true };
- }
-
- if (options.LogRequest)
- {
- _logger.Info("HttpClientManager {0}: {1}", httpMethod.ToUpper(), options.Url);
- }
-
- try
- {
- options.CancellationToken.ThrowIfCancellationRequested();
-
- if (!options.BufferContent)
- {
- var response = await GetResponseAsync(httpWebRequest, TimeSpan.FromMilliseconds(options.TimeoutMs)).ConfigureAwait(false);
-
- var httpResponse = (HttpWebResponse)response;
-
- EnsureSuccessStatusCode(client, httpResponse, options);
-
- options.CancellationToken.ThrowIfCancellationRequested();
-
- return GetResponseInfo(httpResponse, httpResponse.GetResponseStream(), GetContentLength(httpResponse), httpResponse);
- }
-
- using (var response = await GetResponseAsync(httpWebRequest, TimeSpan.FromMilliseconds(options.TimeoutMs)).ConfigureAwait(false))
- {
- var httpResponse = (HttpWebResponse)response;
-
- EnsureSuccessStatusCode(client, httpResponse, options);
-
- options.CancellationToken.ThrowIfCancellationRequested();
-
- using (var stream = httpResponse.GetResponseStream())
- {
- var memoryStream = _memoryStreamProvider.CreateNew();
-
- await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
-
- memoryStream.Position = 0;
-
- return GetResponseInfo(httpResponse, memoryStream, memoryStream.Length, null);
- }
- }
- }
- catch (OperationCanceledException ex)
- {
- throw GetCancellationException(options, client, options.CancellationToken, ex);
- }
- catch (Exception ex)
- {
- throw GetException(ex, options, client);
- }
- finally
- {
- if (options.ResourcePool != null)
- {
- options.ResourcePool.Release();
- }
- }
- }
-
- private HttpResponseInfo GetResponseInfo(HttpWebResponse httpResponse, Stream content, long? contentLength, IDisposable disposable)
- {
- var responseInfo = new HttpResponseInfo(disposable)
- {
- Content = content,
-
- StatusCode = httpResponse.StatusCode,
-
- ContentType = httpResponse.ContentType,
-
- ContentLength = contentLength,
-
- ResponseUrl = httpResponse.ResponseUri.ToString()
- };
-
- if (httpResponse.Headers != null)
- {
- SetHeaders(httpResponse.Headers, responseInfo);
- }
-
- return responseInfo;
- }
-
- private HttpResponseInfo GetResponseInfo(HttpWebResponse httpResponse, string tempFile, long? contentLength)
- {
- var responseInfo = new HttpResponseInfo
- {
- TempFilePath = tempFile,
-
- StatusCode = httpResponse.StatusCode,
-
- ContentType = httpResponse.ContentType,
-
- ContentLength = contentLength
- };
-
- if (httpResponse.Headers != null)
- {
- SetHeaders(httpResponse.Headers, responseInfo);
- }
-
- return responseInfo;
- }
-
- private void SetHeaders(WebHeaderCollection headers, HttpResponseInfo responseInfo)
- {
- foreach (var key in headers.AllKeys)
- {
- responseInfo.Headers[key] = headers[key];
- }
- }
-
- public Task<HttpResponseInfo> Post(HttpRequestOptions options)
- {
- return SendAsync(options, "POST");
- }
-
- /// <summary>
- /// Performs a POST request
- /// </summary>
- /// <param name="options">The options.</param>
- /// <param name="postData">Params to add to the POST data.</param>
- /// <returns>stream on success, null on failure</returns>
- public async Task<Stream> Post(HttpRequestOptions options, Dictionary<string, string> postData)
- {
- options.SetPostData(postData);
-
- var response = await Post(options).ConfigureAwait(false);
-
- return response.Content;
- }
-
- /// <summary>
- /// Performs a POST request
- /// </summary>
- /// <param name="url">The URL.</param>
- /// <param name="postData">Params to add to the POST data.</param>
- /// <param name="resourcePool">The resource pool.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>stream on success, null on failure</returns>
- public Task<Stream> Post(string url, Dictionary<string, string> postData, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
- {
- return Post(new HttpRequestOptions
- {
- Url = url,
- ResourcePool = resourcePool,
- CancellationToken = cancellationToken,
- BufferContent = resourcePool != null
-
- }, postData);
- }
-
- /// <summary>
- /// Downloads the contents of a given url into a temporary location
- /// </summary>
- /// <param name="options">The options.</param>
- /// <returns>Task{System.String}.</returns>
- public async Task<string> GetTempFile(HttpRequestOptions options)
- {
- var response = await GetTempFileResponse(options).ConfigureAwait(false);
-
- return response.TempFilePath;
- }
-
- public async Task<HttpResponseInfo> GetTempFileResponse(HttpRequestOptions options)
- {
- ValidateParams(options);
-
- _fileSystem.CreateDirectory(_appPaths.TempDirectory);
-
- var tempFile = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + ".tmp");
-
- if (options.Progress == null)
- {
- throw new ArgumentNullException("progress");
- }
-
- options.CancellationToken.ThrowIfCancellationRequested();
-
- var httpWebRequest = GetRequest(options, "GET");
-
- if (options.ResourcePool != null)
- {
- await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false);
- }
-
- options.Progress.Report(0);
-
- if (options.LogRequest)
- {
- _logger.Info("HttpClientManager.GetTempFileResponse url: {0}", options.Url);
- }
-
- var client = GetHttpClient(GetHostFromUrl(options.Url), options.EnableHttpCompression);
-
- try
- {
- options.CancellationToken.ThrowIfCancellationRequested();
-
- using (var response = await httpWebRequest.GetResponseAsync().ConfigureAwait(false))
- {
- var httpResponse = (HttpWebResponse)response;
-
- EnsureSuccessStatusCode(client, httpResponse, options);
-
- options.CancellationToken.ThrowIfCancellationRequested();
-
- var contentLength = GetContentLength(httpResponse);
-
- if (!contentLength.HasValue)
- {
- // We're not able to track progress
- using (var stream = httpResponse.GetResponseStream())
- {
- using (var fs = _fileSystem.GetFileStream(tempFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
- {
- await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
- }
- }
- }
- else
- {
- using (var stream = ProgressStream.CreateReadProgressStream(httpResponse.GetResponseStream(), options.Progress.Report, contentLength.Value))
- {
- using (var fs = _fileSystem.GetFileStream(tempFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
- {
- await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
- }
- }
- }
-
- options.Progress.Report(100);
-
- return GetResponseInfo(httpResponse, tempFile, contentLength);
- }
- }
- catch (Exception ex)
- {
- DeleteTempFile(tempFile);
- throw GetException(ex, options, client);
- }
- finally
- {
- if (options.ResourcePool != null)
- {
- options.ResourcePool.Release();
- }
- }
- }
-
- private long? GetContentLength(HttpWebResponse response)
- {
- var length = response.ContentLength;
-
- if (length == 0)
- {
- return null;
- }
-
- return length;
- }
-
- protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
- private Exception GetException(Exception ex, HttpRequestOptions options, HttpClientInfo client)
- {
- if (ex is HttpException)
- {
- return ex;
- }
-
- var webException = ex as WebException
- ?? ex.InnerException as WebException;
-
- if (webException != null)
- {
- if (options.LogErrors)
- {
- _logger.ErrorException("Error getting response from " + options.Url, ex);
- }
-
- var exception = new HttpException(ex.Message, ex);
-
- var response = webException.Response as HttpWebResponse;
- if (response != null)
- {
- exception.StatusCode = response.StatusCode;
-
- if ((int)response.StatusCode == 429)
- {
- client.LastTimeout = DateTime.UtcNow;
- }
- }
-
- return exception;
- }
-
- var operationCanceledException = ex as OperationCanceledException
- ?? ex.InnerException as OperationCanceledException;
-
- if (operationCanceledException != null)
- {
- return GetCancellationException(options, client, options.CancellationToken, operationCanceledException);
- }
-
- if (options.LogErrors)
- {
- _logger.ErrorException("Error getting response from " + options.Url, ex);
- }
-
- return ex;
- }
-
- private void DeleteTempFile(string file)
- {
- try
- {
- _fileSystem.DeleteFile(file);
- }
- catch (IOException)
- {
- // Might not have been created at all. No need to worry.
- }
- }
-
- private void ValidateParams(HttpRequestOptions options)
- {
- if (string.IsNullOrEmpty(options.Url))
- {
- throw new ArgumentNullException("options");
- }
- }
-
- /// <summary>
- /// Gets the host from URL.
- /// </summary>
- /// <param name="url">The URL.</param>
- /// <returns>System.String.</returns>
- private string GetHostFromUrl(string url)
- {
- var index = url.IndexOf("://", StringComparison.OrdinalIgnoreCase);
-
- if (index != -1)
- {
- url = url.Substring(index + 3);
- var host = url.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
-
- if (!string.IsNullOrWhiteSpace(host))
- {
- return host;
- }
- }
-
- return url;
- }
-
- /// <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)
- {
- _httpClients.Clear();
- }
- }
-
- /// <summary>
- /// Throws the cancellation exception.
- /// </summary>
- /// <param name="options">The options.</param>
- /// <param name="client">The client.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="exception">The exception.</param>
- /// <returns>Exception.</returns>
- private Exception GetCancellationException(HttpRequestOptions options, HttpClientInfo client, CancellationToken cancellationToken, OperationCanceledException exception)
- {
- // If the HttpClient's timeout is reached, it will cancel the Task internally
- if (!cancellationToken.IsCancellationRequested)
- {
- var msg = string.Format("Connection to {0} timed out", options.Url);
-
- if (options.LogErrors)
- {
- _logger.Error(msg);
- }
-
- client.LastTimeout = DateTime.UtcNow;
-
- // Throw an HttpException so that the caller doesn't think it was cancelled by user code
- return new HttpException(msg, exception)
- {
- IsTimedOut = true
- };
- }
-
- return exception;
- }
-
- private void EnsureSuccessStatusCode(HttpClientInfo client, HttpWebResponse response, HttpRequestOptions options)
- {
- var statusCode = response.StatusCode;
-
- var isSuccessful = statusCode >= HttpStatusCode.OK && statusCode <= (HttpStatusCode)299;
-
- if (!isSuccessful)
- {
- if (options.LogErrorResponseBody)
- {
- try
- {
- using (var stream = response.GetResponseStream())
- {
- if (stream != null)
- {
- using (var reader = new StreamReader(stream))
- {
- var msg = reader.ReadToEnd();
-
- _logger.Error(msg);
- }
- }
- }
- }
- catch
- {
-
- }
- }
- throw new HttpException(response.StatusDescription)
- {
- StatusCode = response.StatusCode
- };
- }
- }
-
- /// <summary>
- /// Posts the specified URL.
- /// </summary>
- /// <param name="url">The URL.</param>
- /// <param name="postData">The post data.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task{Stream}.</returns>
- public Task<Stream> Post(string url, Dictionary<string, string> postData, CancellationToken cancellationToken)
- {
- return Post(url, postData, null, cancellationToken);
- }
-
- private Task<WebResponse> GetResponseAsync(WebRequest request, TimeSpan timeout)
- {
- var taskCompletion = new TaskCompletionSource<WebResponse>();
-
- Task<WebResponse> asyncTask = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
-
- ThreadPool.RegisterWaitForSingleObject((asyncTask as IAsyncResult).AsyncWaitHandle, TimeoutCallback, request, timeout, true);
- var callback = new TaskCallback { taskCompletion = taskCompletion };
- asyncTask.ContinueWith(callback.OnSuccess, TaskContinuationOptions.NotOnFaulted);
-
- // Handle errors
- asyncTask.ContinueWith(callback.OnError, TaskContinuationOptions.OnlyOnFaulted);
-
- return taskCompletion.Task;
- }
-
- private static void TimeoutCallback(object state, bool timedOut)
- {
- if (timedOut)
- {
- WebRequest request = (WebRequest)state;
- if (state != null)
- {
- request.Abort();
- }
- }
- }
-
- private class TaskCallback
- {
- public TaskCompletionSource<WebResponse> taskCompletion;
-
- public void OnSuccess(Task<WebResponse> task)
- {
- taskCompletion.TrySetResult(task.Result);
- }
-
- public void OnError(Task<WebResponse> task)
- {
- if (task.Exception != null)
- {
- taskCompletion.TrySetException(task.Exception);
- }
- else
- {
- taskCompletion.TrySetException(new List<Exception>());
- }
- }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/IO/IsoManager.cs b/MediaBrowser.Common.Implementations/IO/IsoManager.cs
deleted file mode 100644
index de88ddadab..0000000000
--- a/MediaBrowser.Common.Implementations/IO/IsoManager.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-using MediaBrowser.Model.IO;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Common.Implementations.IO
-{
- /// <summary>
- /// Class IsoManager
- /// </summary>
- public class IsoManager : IIsoManager
- {
- /// <summary>
- /// The _mounters
- /// </summary>
- private readonly List<IIsoMounter> _mounters = new List<IIsoMounter>();
-
- /// <summary>
- /// Mounts the specified iso path.
- /// </summary>
- /// <param name="isoPath">The iso path.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>IsoMount.</returns>
- /// <exception cref="System.ArgumentNullException">isoPath</exception>
- /// <exception cref="System.ArgumentException"></exception>
- public Task<IIsoMount> Mount(string isoPath, CancellationToken cancellationToken)
- {
- if (string.IsNullOrEmpty(isoPath))
- {
- throw new ArgumentNullException("isoPath");
- }
-
- var mounter = _mounters.FirstOrDefault(i => i.CanMount(isoPath));
-
- if (mounter == null)
- {
- throw new ArgumentException(string.Format("No mounters are able to mount {0}", isoPath));
- }
-
- return mounter.Mount(isoPath, cancellationToken);
- }
-
- /// <summary>
- /// Determines whether this instance can mount the specified path.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns><c>true</c> if this instance can mount the specified path; otherwise, <c>false</c>.</returns>
- public bool CanMount(string path)
- {
- return _mounters.Any(i => i.CanMount(path));
- }
-
- /// <summary>
- /// Adds the parts.
- /// </summary>
- /// <param name="mounters">The mounters.</param>
- public void AddParts(IEnumerable<IIsoMounter> mounters)
- {
- _mounters.AddRange(mounters);
- }
-
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
- public void Dispose()
- {
- foreach (var mounter in _mounters)
- {
- mounter.Dispose();
- }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/IO/LnkShortcutHandler.cs b/MediaBrowser.Common.Implementations/IO/LnkShortcutHandler.cs
deleted file mode 100644
index 441e6939f3..0000000000
--- a/MediaBrowser.Common.Implementations/IO/LnkShortcutHandler.cs
+++ /dev/null
@@ -1,399 +0,0 @@
-using System;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Security;
-using System.Text;
-using MediaBrowser.Model.IO;
-
-namespace MediaBrowser.Common.Implementations.IO
-{
- public class LnkShortcutHandler :IShortcutHandler
- {
- public string Extension
- {
- get { return ".lnk"; }
- }
-
- public string Resolve(string shortcutPath)
- {
- var link = new ShellLink();
- ((IPersistFile)link).Load(shortcutPath, NativeMethods.STGM_READ);
- // ((IShellLinkW)link).Resolve(hwnd, 0)
- var sb = new StringBuilder(NativeMethods.MAX_PATH);
- WIN32_FIND_DATA data;
- ((IShellLinkW)link).GetPath(sb, sb.Capacity, out data, 0);
- return sb.ToString();
- }
-
- public void Create(string shortcutPath, string targetPath)
- {
- throw new NotImplementedException();
- }
- }
-
- /// <summary>
- /// Class NativeMethods
- /// </summary>
- [SuppressUnmanagedCodeSecurity]
- public static class NativeMethods
- {
- /// <summary>
- /// The MA x_ PATH
- /// </summary>
- public const int MAX_PATH = 260;
- /// <summary>
- /// The MA x_ ALTERNATE
- /// </summary>
- public const int MAX_ALTERNATE = 14;
- /// <summary>
- /// The INVALI d_ HANDL e_ VALUE
- /// </summary>
- public static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
- /// <summary>
- /// The STG m_ READ
- /// </summary>
- public const uint STGM_READ = 0;
- }
-
- /// <summary>
- /// Struct FILETIME
- /// </summary>
- [StructLayout(LayoutKind.Sequential)]
- public struct FILETIME
- {
- /// <summary>
- /// The dw low date time
- /// </summary>
- public uint dwLowDateTime;
- /// <summary>
- /// The dw high date time
- /// </summary>
- public uint dwHighDateTime;
- }
-
- /// <summary>
- /// Struct WIN32_FIND_DATA
- /// </summary>
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- public struct WIN32_FIND_DATA
- {
- /// <summary>
- /// The dw file attributes
- /// </summary>
- public FileAttributes dwFileAttributes;
- /// <summary>
- /// The ft creation time
- /// </summary>
- public FILETIME ftCreationTime;
- /// <summary>
- /// The ft last access time
- /// </summary>
- public FILETIME ftLastAccessTime;
- /// <summary>
- /// The ft last write time
- /// </summary>
- public FILETIME ftLastWriteTime;
- /// <summary>
- /// The n file size high
- /// </summary>
- public int nFileSizeHigh;
- /// <summary>
- /// The n file size low
- /// </summary>
- public int nFileSizeLow;
- /// <summary>
- /// The dw reserved0
- /// </summary>
- public int dwReserved0;
- /// <summary>
- /// The dw reserved1
- /// </summary>
- public int dwReserved1;
-
- /// <summary>
- /// The c file name
- /// </summary>
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NativeMethods.MAX_PATH)]
- public string cFileName;
-
- /// <summary>
- /// This will always be null when FINDEX_INFO_LEVELS = basic
- /// </summary>
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NativeMethods.MAX_ALTERNATE)]
- public string cAlternate;
-
- /// <summary>
- /// Gets or sets the path.
- /// </summary>
- /// <value>The path.</value>
- public string Path { get; set; }
-
- /// <summary>
- /// Returns a <see cref="System.String" /> that represents this instance.
- /// </summary>
- /// <returns>A <see cref="System.String" /> that represents this instance.</returns>
- public override string ToString()
- {
- return Path ?? string.Empty;
- }
- }
-
- /// <summary>
- /// Enum SLGP_FLAGS
- /// </summary>
- [Flags]
- public enum SLGP_FLAGS
- {
- /// <summary>
- /// Retrieves the standard short (8.3 format) file name
- /// </summary>
- SLGP_SHORTPATH = 0x1,
- /// <summary>
- /// Retrieves the Universal Naming Convention (UNC) path name of the file
- /// </summary>
- SLGP_UNCPRIORITY = 0x2,
- /// <summary>
- /// Retrieves the raw path name. A raw path is something that might not exist and may include environment variables that need to be expanded
- /// </summary>
- SLGP_RAWPATH = 0x4
- }
- /// <summary>
- /// Enum SLR_FLAGS
- /// </summary>
- [Flags]
- public enum SLR_FLAGS
- {
- /// <summary>
- /// Do not display a dialog box if the link cannot be resolved. When SLR_NO_UI is set,
- /// the high-order word of fFlags can be set to a time-out value that specifies the
- /// maximum amount of time to be spent resolving the link. The function returns if the
- /// link cannot be resolved within the time-out duration. If the high-order word is set
- /// to zero, the time-out duration will be set to the default value of 3,000 milliseconds
- /// (3 seconds). To specify a value, set the high word of fFlags to the desired time-out
- /// duration, in milliseconds.
- /// </summary>
- SLR_NO_UI = 0x1,
- /// <summary>
- /// Obsolete and no longer used
- /// </summary>
- SLR_ANY_MATCH = 0x2,
- /// <summary>
- /// If the link object has changed, update its path and list of identifiers.
- /// If SLR_UPDATE is set, you do not need to call IPersistFile::IsDirty to determine
- /// whether or not the link object has changed.
- /// </summary>
- SLR_UPDATE = 0x4,
- /// <summary>
- /// Do not update the link information
- /// </summary>
- SLR_NOUPDATE = 0x8,
- /// <summary>
- /// Do not execute the search heuristics
- /// </summary>
- SLR_NOSEARCH = 0x10,
- /// <summary>
- /// Do not use distributed link tracking
- /// </summary>
- SLR_NOTRACK = 0x20,
- /// <summary>
- /// Disable distributed link tracking. By default, distributed link tracking tracks
- /// removable media across multiple devices based on the volume name. It also uses the
- /// Universal Naming Convention (UNC) path to track remote file systems whose drive letter
- /// has changed. Setting SLR_NOLINKINFO disables both types of tracking.
- /// </summary>
- SLR_NOLINKINFO = 0x40,
- /// <summary>
- /// Call the Microsoft Windows Installer
- /// </summary>
- SLR_INVOKE_MSI = 0x80
- }
-
- /// <summary>
- /// The IShellLink interface allows Shell links to be created, modified, and resolved
- /// </summary>
- [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214F9-0000-0000-C000-000000000046")]
- public interface IShellLinkW
- {
- /// <summary>
- /// Retrieves the path and file name of a Shell link object
- /// </summary>
- /// <param name="pszFile">The PSZ file.</param>
- /// <param name="cchMaxPath">The CCH max path.</param>
- /// <param name="pfd">The PFD.</param>
- /// <param name="fFlags">The f flags.</param>
- void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out WIN32_FIND_DATA pfd, SLGP_FLAGS fFlags);
- /// <summary>
- /// Retrieves the list of item identifiers for a Shell link object
- /// </summary>
- /// <param name="ppidl">The ppidl.</param>
- void GetIDList(out IntPtr ppidl);
- /// <summary>
- /// Sets the pointer to an item identifier list (PIDL) for a Shell link object.
- /// </summary>
- /// <param name="pidl">The pidl.</param>
- void SetIDList(IntPtr pidl);
- /// <summary>
- /// Retrieves the description string for a Shell link object
- /// </summary>
- /// <param name="pszName">Name of the PSZ.</param>
- /// <param name="cchMaxName">Name of the CCH max.</param>
- void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
- /// <summary>
- /// Sets the description for a Shell link object. The description can be any application-defined string
- /// </summary>
- /// <param name="pszName">Name of the PSZ.</param>
- void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
- /// <summary>
- /// Retrieves the name of the working directory for a Shell link object
- /// </summary>
- /// <param name="pszDir">The PSZ dir.</param>
- /// <param name="cchMaxPath">The CCH max path.</param>
- void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
- /// <summary>
- /// Sets the name of the working directory for a Shell link object
- /// </summary>
- /// <param name="pszDir">The PSZ dir.</param>
- void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
- /// <summary>
- /// Retrieves the command-line arguments associated with a Shell link object
- /// </summary>
- /// <param name="pszArgs">The PSZ args.</param>
- /// <param name="cchMaxPath">The CCH max path.</param>
- void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
- /// <summary>
- /// Sets the command-line arguments for a Shell link object
- /// </summary>
- /// <param name="pszArgs">The PSZ args.</param>
- void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
- /// <summary>
- /// Retrieves the hot key for a Shell link object
- /// </summary>
- /// <param name="pwHotkey">The pw hotkey.</param>
- void GetHotkey(out short pwHotkey);
- /// <summary>
- /// Sets a hot key for a Shell link object
- /// </summary>
- /// <param name="wHotkey">The w hotkey.</param>
- void SetHotkey(short wHotkey);
- /// <summary>
- /// Retrieves the show command for a Shell link object
- /// </summary>
- /// <param name="piShowCmd">The pi show CMD.</param>
- void GetShowCmd(out int piShowCmd);
- /// <summary>
- /// Sets the show command for a Shell link object. The show command sets the initial show state of the window.
- /// </summary>
- /// <param name="iShowCmd">The i show CMD.</param>
- void SetShowCmd(int iShowCmd);
- /// <summary>
- /// Retrieves the location (path and index) of the icon for a Shell link object
- /// </summary>
- /// <param name="pszIconPath">The PSZ icon path.</param>
- /// <param name="cchIconPath">The CCH icon path.</param>
- /// <param name="piIcon">The pi icon.</param>
- void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath,
- int cchIconPath, out int piIcon);
- /// <summary>
- /// Sets the location (path and index) of the icon for a Shell link object
- /// </summary>
- /// <param name="pszIconPath">The PSZ icon path.</param>
- /// <param name="iIcon">The i icon.</param>
- void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
- /// <summary>
- /// Sets the relative path to the Shell link object
- /// </summary>
- /// <param name="pszPathRel">The PSZ path rel.</param>
- /// <param name="dwReserved">The dw reserved.</param>
- void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
- /// <summary>
- /// Attempts to find the target of a Shell link, even if it has been moved or renamed
- /// </summary>
- /// <param name="hwnd">The HWND.</param>
- /// <param name="fFlags">The f flags.</param>
- void Resolve(IntPtr hwnd, SLR_FLAGS fFlags);
- /// <summary>
- /// Sets the path and file name of a Shell link object
- /// </summary>
- /// <param name="pszFile">The PSZ file.</param>
- void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
-
- }
-
- /// <summary>
- /// Interface IPersist
- /// </summary>
- [ComImport, Guid("0000010c-0000-0000-c000-000000000046"),
- InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- public interface IPersist
- {
- /// <summary>
- /// Gets the class ID.
- /// </summary>
- /// <param name="pClassID">The p class ID.</param>
- [PreserveSig]
- void GetClassID(out Guid pClassID);
- }
-
- /// <summary>
- /// Interface IPersistFile
- /// </summary>
- [ComImport, Guid("0000010b-0000-0000-C000-000000000046"),
- InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- public interface IPersistFile : IPersist
- {
- /// <summary>
- /// Gets the class ID.
- /// </summary>
- /// <param name="pClassID">The p class ID.</param>
- new void GetClassID(out Guid pClassID);
- /// <summary>
- /// Determines whether this instance is dirty.
- /// </summary>
- [PreserveSig]
- int IsDirty();
-
- /// <summary>
- /// Loads the specified PSZ file name.
- /// </summary>
- /// <param name="pszFileName">Name of the PSZ file.</param>
- /// <param name="dwMode">The dw mode.</param>
- [PreserveSig]
- void Load([In, MarshalAs(UnmanagedType.LPWStr)]
- string pszFileName, uint dwMode);
-
- /// <summary>
- /// Saves the specified PSZ file name.
- /// </summary>
- /// <param name="pszFileName">Name of the PSZ file.</param>
- /// <param name="remember">if set to <c>true</c> [remember].</param>
- [PreserveSig]
- void Save([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
- [In, MarshalAs(UnmanagedType.Bool)] bool remember);
-
- /// <summary>
- /// Saves the completed.
- /// </summary>
- /// <param name="pszFileName">Name of the PSZ file.</param>
- [PreserveSig]
- void SaveCompleted([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName);
-
- /// <summary>
- /// Gets the cur file.
- /// </summary>
- /// <param name="ppszFileName">Name of the PPSZ file.</param>
- [PreserveSig]
- void GetCurFile([In, MarshalAs(UnmanagedType.LPWStr)] string ppszFileName);
- }
-
- // CLSID_ShellLink from ShlGuid.h
- /// <summary>
- /// Class ShellLink
- /// </summary>
- [
- ComImport,
- Guid("00021401-0000-0000-C000-000000000046")
- ]
- public class ShellLink
- {
- }
-}
diff --git a/MediaBrowser.Common.Implementations/IO/ManagedFileSystem.cs b/MediaBrowser.Common.Implementations/IO/ManagedFileSystem.cs
deleted file mode 100644
index ffb1e42346..0000000000
--- a/MediaBrowser.Common.Implementations/IO/ManagedFileSystem.cs
+++ /dev/null
@@ -1,696 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.IO;
-using Patterns.Logging;
-
-namespace MediaBrowser.Common.Implementations.IO
-{
- /// <summary>
- /// Class ManagedFileSystem
- /// </summary>
- public class ManagedFileSystem : IFileSystem
- {
- protected ILogger Logger;
-
- private readonly bool _supportsAsyncFileStreams;
- private char[] _invalidFileNameChars;
- private readonly List<IShortcutHandler> _shortcutHandlers = new List<IShortcutHandler>();
- protected bool EnableFileSystemRequestConcat = true;
-
- public ManagedFileSystem(ILogger logger, bool supportsAsyncFileStreams, bool enableManagedInvalidFileNameChars)
- {
- Logger = logger;
- _supportsAsyncFileStreams = supportsAsyncFileStreams;
- SetInvalidFileNameChars(enableManagedInvalidFileNameChars);
- }
-
- public void AddShortcutHandler(IShortcutHandler handler)
- {
- _shortcutHandlers.Add(handler);
- }
-
- protected void SetInvalidFileNameChars(bool enableManagedInvalidFileNameChars)
- {
- if (enableManagedInvalidFileNameChars)
- {
- _invalidFileNameChars = Path.GetInvalidFileNameChars();
- }
- else
- {
- // GetInvalidFileNameChars is less restrictive in Linux/Mac than Windows, this mimic Windows behavior for mono under Linux/Mac.
- _invalidFileNameChars = new char[41] { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
- '\x08', '\x09', '\x0A', '\x0B', '\x0C', '\x0D', '\x0E', '\x0F', '\x10', '\x11', '\x12',
- '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', '\x1A', '\x1B', '\x1C', '\x1D',
- '\x1E', '\x1F', '\x22', '\x3C', '\x3E', '\x7C', ':', '*', '?', '\\', '/' };
- }
- }
-
- public char DirectorySeparatorChar
- {
- get
- {
- return Path.DirectorySeparatorChar;
- }
- }
-
- public string GetFullPath(string path)
- {
- return Path.GetFullPath(path);
- }
-
- /// <summary>
- /// Determines whether the specified filename is shortcut.
- /// </summary>
- /// <param name="filename">The filename.</param>
- /// <returns><c>true</c> if the specified filename is shortcut; otherwise, <c>false</c>.</returns>
- /// <exception cref="System.ArgumentNullException">filename</exception>
- public virtual bool IsShortcut(string filename)
- {
- if (string.IsNullOrEmpty(filename))
- {
- throw new ArgumentNullException("filename");
- }
-
- var extension = Path.GetExtension(filename);
- return _shortcutHandlers.Any(i => string.Equals(extension, i.Extension, StringComparison.OrdinalIgnoreCase));
- }
-
- /// <summary>
- /// Resolves the shortcut.
- /// </summary>
- /// <param name="filename">The filename.</param>
- /// <returns>System.String.</returns>
- /// <exception cref="System.ArgumentNullException">filename</exception>
- public virtual string ResolveShortcut(string filename)
- {
- if (string.IsNullOrEmpty(filename))
- {
- throw new ArgumentNullException("filename");
- }
-
- var extension = Path.GetExtension(filename);
- var handler = _shortcutHandlers.FirstOrDefault(i => string.Equals(extension, i.Extension, StringComparison.OrdinalIgnoreCase));
-
- if (handler != null)
- {
- return handler.Resolve(filename);
- }
-
- return null;
- }
-
- /// <summary>
- /// Creates the shortcut.
- /// </summary>
- /// <param name="shortcutPath">The shortcut path.</param>
- /// <param name="target">The target.</param>
- /// <exception cref="System.ArgumentNullException">
- /// shortcutPath
- /// or
- /// target
- /// </exception>
- public void CreateShortcut(string shortcutPath, string target)
- {
- if (string.IsNullOrEmpty(shortcutPath))
- {
- throw new ArgumentNullException("shortcutPath");
- }
-
- if (string.IsNullOrEmpty(target))
- {
- throw new ArgumentNullException("target");
- }
-
- var extension = Path.GetExtension(shortcutPath);
- var handler = _shortcutHandlers.FirstOrDefault(i => string.Equals(extension, i.Extension, StringComparison.OrdinalIgnoreCase));
-
- if (handler != null)
- {
- handler.Create(shortcutPath, target);
- }
- else
- {
- throw new NotImplementedException();
- }
- }
-
- /// <summary>
- /// Returns a <see cref="FileSystemMetadata"/> object for the specified file or directory path.
- /// </summary>
- /// <param name="path">A path to a file or directory.</param>
- /// <returns>A <see cref="FileSystemMetadata"/> object.</returns>
- /// <remarks>If the specified path points to a directory, the returned <see cref="FileSystemMetadata"/> object's
- /// <see cref="FileSystemMetadata.IsDirectory"/> property will be set to true and all other properties will reflect the properties of the directory.</remarks>
- public FileSystemMetadata GetFileSystemInfo(string path)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException("path");
- }
-
- // Take a guess to try and avoid two file system hits, but we'll double-check by calling Exists
- if (Path.HasExtension(path))
- {
- var fileInfo = new FileInfo(path);
-
- if (fileInfo.Exists)
- {
- return GetFileSystemMetadata(fileInfo);
- }
-
- return GetFileSystemMetadata(new DirectoryInfo(path));
- }
- else
- {
- var fileInfo = new DirectoryInfo(path);
-
- if (fileInfo.Exists)
- {
- return GetFileSystemMetadata(fileInfo);
- }
-
- return GetFileSystemMetadata(new FileInfo(path));
- }
- }
-
- /// <summary>
- /// Returns a <see cref="FileSystemMetadata"/> object for the specified file path.
- /// </summary>
- /// <param name="path">A path to a file.</param>
- /// <returns>A <see cref="FileSystemMetadata"/> object.</returns>
- /// <remarks><para>If the specified path points to a directory, the returned <see cref="FileSystemMetadata"/> object's
- /// <see cref="FileSystemMetadata.IsDirectory"/> property and the <see cref="FileSystemMetadata.Exists"/> property will both be set to false.</para>
- /// <para>For automatic handling of files <b>and</b> directories, use <see cref="GetFileSystemInfo"/>.</para></remarks>
- public FileSystemMetadata GetFileInfo(string path)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException("path");
- }
-
- var fileInfo = new FileInfo(path);
-
- return GetFileSystemMetadata(fileInfo);
- }
-
- /// <summary>
- /// Returns a <see cref="FileSystemMetadata"/> object for the specified directory path.
- /// </summary>
- /// <param name="path">A path to a directory.</param>
- /// <returns>A <see cref="FileSystemMetadata"/> object.</returns>
- /// <remarks><para>If the specified path points to a file, the returned <see cref="FileSystemMetadata"/> object's
- /// <see cref="FileSystemMetadata.IsDirectory"/> property will be set to true and the <see cref="FileSystemMetadata.Exists"/> property will be set to false.</para>
- /// <para>For automatic handling of files <b>and</b> directories, use <see cref="GetFileSystemInfo"/>.</para></remarks>
- public FileSystemMetadata GetDirectoryInfo(string path)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException("path");
- }
-
- var fileInfo = new DirectoryInfo(path);
-
- return GetFileSystemMetadata(fileInfo);
- }
-
- private FileSystemMetadata GetFileSystemMetadata(FileSystemInfo info)
- {
- var result = new FileSystemMetadata();
-
- result.Exists = info.Exists;
- result.FullName = info.FullName;
- result.Extension = info.Extension;
- result.Name = info.Name;
-
- if (result.Exists)
- {
- var attributes = info.Attributes;
- result.IsDirectory = info is DirectoryInfo || (attributes & FileAttributes.Directory) == FileAttributes.Directory;
- result.IsHidden = (attributes & FileAttributes.Hidden) == FileAttributes.Hidden;
- result.IsReadOnly = (attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly;
-
- var fileInfo = info as FileInfo;
- if (fileInfo != null)
- {
- result.Length = fileInfo.Length;
- result.DirectoryName = fileInfo.DirectoryName;
- }
-
- result.CreationTimeUtc = GetCreationTimeUtc(info);
- result.LastWriteTimeUtc = GetLastWriteTimeUtc(info);
- }
- else
- {
- result.IsDirectory = info is DirectoryInfo;
- }
-
- return result;
- }
-
- /// <summary>
- /// The space char
- /// </summary>
- private const char SpaceChar = ' ';
-
- /// <summary>
- /// Takes a filename and removes invalid characters
- /// </summary>
- /// <param name="filename">The filename.</param>
- /// <returns>System.String.</returns>
- /// <exception cref="System.ArgumentNullException">filename</exception>
- public string GetValidFilename(string filename)
- {
- if (string.IsNullOrEmpty(filename))
- {
- throw new ArgumentNullException("filename");
- }
-
- var builder = new StringBuilder(filename);
-
- foreach (var c in _invalidFileNameChars)
- {
- builder = builder.Replace(c, SpaceChar);
- }
-
- return builder.ToString();
- }
-
- /// <summary>
- /// Gets the creation time UTC.
- /// </summary>
- /// <param name="info">The info.</param>
- /// <returns>DateTime.</returns>
- public DateTime GetCreationTimeUtc(FileSystemInfo info)
- {
- // This could throw an error on some file systems that have dates out of range
- try
- {
- return info.CreationTimeUtc;
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error determining CreationTimeUtc for {0}", ex, info.FullName);
- return DateTime.MinValue;
- }
- }
-
- /// <summary>
- /// Gets the creation time UTC.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns>DateTime.</returns>
- public DateTime GetCreationTimeUtc(string path)
- {
- return GetCreationTimeUtc(GetFileSystemInfo(path));
- }
-
- public DateTime GetCreationTimeUtc(FileSystemMetadata info)
- {
- return info.CreationTimeUtc;
- }
-
- public DateTime GetLastWriteTimeUtc(FileSystemMetadata info)
- {
- return info.LastWriteTimeUtc;
- }
-
- /// <summary>
- /// Gets the creation time UTC.
- /// </summary>
- /// <param name="info">The info.</param>
- /// <returns>DateTime.</returns>
- public DateTime GetLastWriteTimeUtc(FileSystemInfo info)
- {
- // This could throw an error on some file systems that have dates out of range
- try
- {
- return info.LastWriteTimeUtc;
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error determining LastAccessTimeUtc for {0}", ex, info.FullName);
- return DateTime.MinValue;
- }
- }
-
- /// <summary>
- /// Gets the last write time UTC.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns>DateTime.</returns>
- public DateTime GetLastWriteTimeUtc(string path)
- {
- return GetLastWriteTimeUtc(GetFileSystemInfo(path));
- }
-
- /// <summary>
- /// Gets the file stream.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <param name="mode">The mode.</param>
- /// <param name="access">The access.</param>
- /// <param name="share">The share.</param>
- /// <param name="isAsync">if set to <c>true</c> [is asynchronous].</param>
- /// <returns>FileStream.</returns>
- public Stream GetFileStream(string path, FileOpenMode mode, FileAccessMode access, FileShareMode share, bool isAsync = false)
- {
- if (_supportsAsyncFileStreams && isAsync)
- {
- return new FileStream(path, GetFileMode(mode), GetFileAccess(access), GetFileShare(share), 262144, true);
- }
-
- return new FileStream(path, GetFileMode(mode), GetFileAccess(access), GetFileShare(share), 262144);
- }
-
- private FileMode GetFileMode(FileOpenMode mode)
- {
- switch (mode)
- {
- case FileOpenMode.Append:
- return FileMode.Append;
- case FileOpenMode.Create:
- return FileMode.Create;
- case FileOpenMode.CreateNew:
- return FileMode.CreateNew;
- case FileOpenMode.Open:
- return FileMode.Open;
- case FileOpenMode.OpenOrCreate:
- return FileMode.OpenOrCreate;
- case FileOpenMode.Truncate:
- return FileMode.Truncate;
- default:
- throw new Exception("Unrecognized FileOpenMode");
- }
- }
-
- private FileAccess GetFileAccess(FileAccessMode mode)
- {
- var val = (int)mode;
-
- return (FileAccess)val;
- }
-
- private FileShare GetFileShare(FileShareMode mode)
- {
- var val = (int)mode;
-
- return (FileShare)val;
- }
-
- public void SetHidden(string path, bool isHidden)
- {
- var info = GetFileInfo(path);
-
- if (info.Exists && info.IsHidden != isHidden)
- {
- if (isHidden)
- {
- FileAttributes attributes = File.GetAttributes(path);
- attributes = RemoveAttribute(attributes, FileAttributes.Hidden);
- File.SetAttributes(path, attributes);
- }
- else
- {
- File.SetAttributes(path, File.GetAttributes(path) | FileAttributes.Hidden);
- }
- }
- }
-
- private static FileAttributes RemoveAttribute(FileAttributes attributes, FileAttributes attributesToRemove)
- {
- return attributes & ~attributesToRemove;
- }
-
- /// <summary>
- /// Swaps the files.
- /// </summary>
- /// <param name="file1">The file1.</param>
- /// <param name="file2">The file2.</param>
- public void SwapFiles(string file1, string file2)
- {
- if (string.IsNullOrEmpty(file1))
- {
- throw new ArgumentNullException("file1");
- }
-
- if (string.IsNullOrEmpty(file2))
- {
- throw new ArgumentNullException("file2");
- }
-
- var temp1 = Path.GetTempFileName();
- var temp2 = Path.GetTempFileName();
-
- // Copying over will fail against hidden files
- RemoveHiddenAttribute(file1);
- RemoveHiddenAttribute(file2);
-
- CopyFile(file1, temp1, true);
- CopyFile(file2, temp2, true);
-
- CopyFile(temp1, file2, true);
- CopyFile(temp2, file1, true);
-
- DeleteFile(temp1);
- DeleteFile(temp2);
- }
-
- /// <summary>
- /// Removes the hidden attribute.
- /// </summary>
- /// <param name="path">The path.</param>
- private void RemoveHiddenAttribute(string path)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException("path");
- }
-
- var currentFile = new FileInfo(path);
-
- // This will fail if the file is hidden
- if (currentFile.Exists)
- {
- if ((currentFile.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
- {
- currentFile.Attributes &= ~FileAttributes.Hidden;
- }
- }
- }
-
- public bool ContainsSubPath(string parentPath, string path)
- {
- if (string.IsNullOrEmpty(parentPath))
- {
- throw new ArgumentNullException("parentPath");
- }
-
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException("path");
- }
-
- return path.IndexOf(parentPath.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) != -1;
- }
-
- public bool IsRootPath(string path)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException("path");
- }
-
- var parent = Path.GetDirectoryName(path);
-
- if (!string.IsNullOrEmpty(parent))
- {
- return false;
- }
-
- return true;
- }
-
- public string NormalizePath(string path)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException("path");
- }
-
- if (path.EndsWith(":\\", StringComparison.OrdinalIgnoreCase))
- {
- return path;
- }
-
- return path.TrimEnd(Path.DirectorySeparatorChar);
- }
-
- public string GetFileNameWithoutExtension(FileSystemMetadata info)
- {
- if (info.IsDirectory)
- {
- return info.Name;
- }
-
- return Path.GetFileNameWithoutExtension(info.FullName);
- }
-
- public string GetFileNameWithoutExtension(string path)
- {
- return Path.GetFileNameWithoutExtension(path);
- }
-
- public bool IsPathFile(string path)
- {
- if (string.IsNullOrWhiteSpace(path))
- {
- throw new ArgumentNullException("path");
- }
-
- // Cannot use Path.IsPathRooted because it returns false under mono when using windows-based paths, e.g. C:\\
-
- if (path.IndexOf("://", StringComparison.OrdinalIgnoreCase) != -1 &&
- !path.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
- {
- return false;
- }
- return true;
-
- //return Path.IsPathRooted(path);
- }
-
- public void DeleteFile(string path)
- {
- File.Delete(path);
- }
-
- public void DeleteDirectory(string path, bool recursive)
- {
- Directory.Delete(path, recursive);
- }
-
- public void CreateDirectory(string path)
- {
- Directory.CreateDirectory(path);
- }
-
- public IEnumerable<FileSystemMetadata> GetDirectories(string path, bool recursive = false)
- {
- var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
-
- return ToMetadata(path, new DirectoryInfo(path).EnumerateDirectories("*", searchOption));
- }
-
- public IEnumerable<FileSystemMetadata> GetFiles(string path, bool recursive = false)
- {
- var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
-
- return ToMetadata(path, new DirectoryInfo(path).EnumerateFiles("*", searchOption));
- }
-
- public IEnumerable<FileSystemMetadata> GetFileSystemEntries(string path, bool recursive = false)
- {
- var directoryInfo = new DirectoryInfo(path);
- var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
-
- if (EnableFileSystemRequestConcat)
- {
- return ToMetadata(path, directoryInfo.EnumerateDirectories("*", searchOption))
- .Concat(ToMetadata(path, directoryInfo.EnumerateFiles("*", searchOption)));
- }
-
- return ToMetadata(path, directoryInfo.EnumerateFileSystemInfos("*", searchOption));
- }
-
- private IEnumerable<FileSystemMetadata> ToMetadata(string parentPath, IEnumerable<FileSystemInfo> infos)
- {
- return infos.Select(i =>
- {
- try
- {
- return GetFileSystemMetadata(i);
- }
- catch (PathTooLongException)
- {
- // Can't log using the FullName because it will throw the PathTooLongExceptiona again
- //Logger.Warn("Path too long: {0}", i.FullName);
- Logger.Warn("File or directory path too long. Parent folder: {0}", parentPath);
- return null;
- }
-
- }).Where(i => i != null);
- }
-
- public Stream OpenRead(string path)
- {
- return File.OpenRead(path);
- }
-
- public void CopyFile(string source, string target, bool overwrite)
- {
- File.Copy(source, target, overwrite);
- }
-
- public void MoveFile(string source, string target)
- {
- File.Move(source, target);
- }
-
- public void MoveDirectory(string source, string target)
- {
- Directory.Move(source, target);
- }
-
- public bool DirectoryExists(string path)
- {
- return Directory.Exists(path);
- }
-
- public bool FileExists(string path)
- {
- return File.Exists(path);
- }
-
- public string ReadAllText(string path)
- {
- return File.ReadAllText(path);
- }
-
- public void WriteAllText(string path, string text, Encoding encoding)
- {
- File.WriteAllText(path, text, encoding);
- }
-
- public void WriteAllText(string path, string text)
- {
- File.WriteAllText(path, text);
- }
-
- public string ReadAllText(string path, Encoding encoding)
- {
- return File.ReadAllText(path, encoding);
- }
-
- public IEnumerable<string> GetDirectoryPaths(string path, bool recursive = false)
- {
- var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
- return Directory.EnumerateDirectories(path, "*", searchOption);
- }
-
- public IEnumerable<string> GetFilePaths(string path, bool recursive = false)
- {
- var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
- return Directory.EnumerateFiles(path, "*", searchOption);
- }
-
- public IEnumerable<string> GetFileSystemEntryPaths(string path, bool recursive = false)
- {
- var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
- return Directory.EnumerateFileSystemEntries(path, "*", searchOption);
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/IO/WindowsFileSystem.cs b/MediaBrowser.Common.Implementations/IO/WindowsFileSystem.cs
deleted file mode 100644
index e8f8de8aef..0000000000
--- a/MediaBrowser.Common.Implementations/IO/WindowsFileSystem.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using Patterns.Logging;
-
-namespace MediaBrowser.Common.Implementations.IO
-{
- public class WindowsFileSystem : ManagedFileSystem
- {
- public WindowsFileSystem(ILogger logger)
- : base(logger, true, true)
- {
- AddShortcutHandler(new LnkShortcutHandler());
- EnableFileSystemRequestConcat = false;
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Logging/LogHelper.cs b/MediaBrowser.Common.Implementations/Logging/LogHelper.cs
deleted file mode 100644
index 8080c2111c..0000000000
--- a/MediaBrowser.Common.Implementations/Logging/LogHelper.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-using System;
-using System.Text;
-
-namespace MediaBrowser.Common.Implementations.Logging
-{
- /// <summary>
- /// Class LogHelper
- /// </summary>
- public static class LogHelper
- {
- /// <summary>
- /// Gets the log message.
- /// </summary>
- /// <param name="exception">The exception.</param>
- /// <returns>StringBuilder.</returns>
- public static StringBuilder GetLogMessage(Exception exception)
- {
- if (exception == null)
- {
- throw new ArgumentNullException("exception");
- }
-
- var messageText = new StringBuilder();
-
- messageText.AppendLine(exception.Message);
-
- messageText.AppendLine(exception.GetType().FullName);
-
- LogExceptionData(messageText, exception);
-
- messageText.AppendLine(exception.StackTrace ?? "No Stack Trace Available");
-
- // Log the InnerExceptions, if any
- AppendInnerExceptions(messageText, exception);
-
- messageText.AppendLine(string.Empty);
-
- return messageText;
- }
-
- /// <summary>
- /// Appends the inner exceptions.
- /// </summary>
- /// <param name="messageText">The message text.</param>
- /// <param name="e">The e.</param>
- private static void AppendInnerExceptions(StringBuilder messageText, Exception e)
- {
- var aggregate = e as AggregateException;
-
- if (aggregate != null && aggregate.InnerExceptions != null)
- {
- foreach (var ex in aggregate.InnerExceptions)
- {
- AppendInnerException(messageText, ex);
- AppendInnerExceptions(messageText, ex);
- }
- }
-
- else if (e.InnerException != null)
- {
- AppendInnerException(messageText, e.InnerException);
- AppendInnerExceptions(messageText, e.InnerException);
- }
- }
-
- /// <summary>
- /// Appends the inner exception.
- /// </summary>
- /// <param name="messageText">The message text.</param>
- /// <param name="e">The e.</param>
- private static void AppendInnerException(StringBuilder messageText, Exception e)
- {
- messageText.AppendLine("InnerException: " + e.GetType().FullName);
- messageText.AppendLine(e.Message);
-
- LogExceptionData(messageText, e);
-
- if (e.StackTrace != null)
- {
- messageText.AppendLine(e.StackTrace);
- }
- }
-
- /// <summary>
- /// Logs the exception data.
- /// </summary>
- /// <param name="messageText">The message text.</param>
- /// <param name="e">The e.</param>
- private static void LogExceptionData(StringBuilder messageText, Exception e)
- {
- foreach (var key in e.Data.Keys)
- {
- messageText.AppendLine(key + ": " + e.Data[key]);
- }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Logging/NLogger.cs b/MediaBrowser.Common.Implementations/Logging/NLogger.cs
deleted file mode 100644
index 11f41261a2..0000000000
--- a/MediaBrowser.Common.Implementations/Logging/NLogger.cs
+++ /dev/null
@@ -1,224 +0,0 @@
-using MediaBrowser.Model.Logging;
-using System;
-using System.Text;
-
-namespace MediaBrowser.Common.Implementations.Logging
-{
- /// <summary>
- /// Class NLogger
- /// </summary>
- public class NLogger : ILogger
- {
- /// <summary>
- /// The _logger
- /// </summary>
- private readonly NLog.Logger _logger;
-
- private readonly ILogManager _logManager;
-
- /// <summary>
- /// The _lock object
- /// </summary>
- private static readonly object LockObject = new object();
-
- /// <summary>
- /// Initializes a new instance of the <see cref="NLogger" /> class.
- /// </summary>
- /// <param name="name">The name.</param>
- /// <param name="logManager">The log manager.</param>
- public NLogger(string name, ILogManager logManager)
- {
- _logManager = logManager;
- lock (LockObject)
- {
- _logger = NLog.LogManager.GetLogger(name);
- }
- }
-
- /// <summary>
- /// Infoes the specified message.
- /// </summary>
- /// <param name="message">The message.</param>
- /// <param name="paramList">The param list.</param>
- public void Info(string message, params object[] paramList)
- {
- _logger.Info(message, paramList);
- }
-
- /// <summary>
- /// Errors the specified message.
- /// </summary>
- /// <param name="message">The message.</param>
- /// <param name="paramList">The param list.</param>
- public void Error(string message, params object[] paramList)
- {
- _logger.Error(message, paramList);
- }
-
- /// <summary>
- /// Warns the specified message.
- /// </summary>
- /// <param name="message">The message.</param>
- /// <param name="paramList">The param list.</param>
- public void Warn(string message, params object[] paramList)
- {
- _logger.Warn(message, paramList);
- }
-
- /// <summary>
- /// Debugs the specified message.
- /// </summary>
- /// <param name="message">The message.</param>
- /// <param name="paramList">The param list.</param>
- public void Debug(string message, params object[] paramList)
- {
- if (_logManager.LogSeverity == LogSeverity.Info)
- {
- return;
- }
-
- _logger.Debug(message, paramList);
- }
-
- /// <summary>
- /// Logs the exception.
- /// </summary>
- /// <param name="message">The message.</param>
- /// <param name="exception">The exception.</param>
- /// <param name="paramList">The param list.</param>
- /// <exception cref="System.NotImplementedException"></exception>
- public void ErrorException(string message, Exception exception, params object[] paramList)
- {
- LogException(LogSeverity.Error, message, exception, paramList);
- }
-
- /// <summary>
- /// Logs the exception.
- /// </summary>
- /// <param name="level">The level.</param>
- /// <param name="message">The message.</param>
- /// <param name="exception">The exception.</param>
- /// <param name="paramList">The param list.</param>
- private void LogException(LogSeverity level, string message, Exception exception, params object[] paramList)
- {
- message = FormatMessage(message, paramList).Replace(Environment.NewLine, ". ");
-
- var messageText = LogHelper.GetLogMessage(exception);
-
- var prefix = _logManager.ExceptionMessagePrefix;
-
- if (!string.IsNullOrWhiteSpace(prefix))
- {
- messageText.Insert(0, prefix);
- }
-
- LogMultiline(message, level, messageText);
- }
-
- /// <summary>
- /// Formats the message.
- /// </summary>
- /// <param name="message">The message.</param>
- /// <param name="paramList">The param list.</param>
- /// <returns>System.String.</returns>
- private static string FormatMessage(string message, params object[] paramList)
- {
- if (paramList != null)
- {
- for (var i = 0; i < paramList.Length; i++)
- {
- var obj = paramList[i];
-
- message = message.Replace("{" + i + "}", (obj == null ? "null" : obj.ToString()));
- }
- }
-
- return message;
- }
-
- /// <summary>
- /// Logs the multiline.
- /// </summary>
- /// <param name="message">The message.</param>
- /// <param name="severity">The severity.</param>
- /// <param name="additionalContent">Content of the additional.</param>
- public void LogMultiline(string message, LogSeverity severity, StringBuilder additionalContent)
- {
- if (severity == LogSeverity.Debug && _logManager.LogSeverity == LogSeverity.Info)
- {
- return;
- }
-
- additionalContent.Insert(0, message + Environment.NewLine);
-
- const char tabChar = '\t';
-
- var text = additionalContent.ToString()
- .Replace(Environment.NewLine, Environment.NewLine + tabChar)
- .TrimEnd(tabChar);
-
- if (text.EndsWith(Environment.NewLine))
- {
- text = text.Substring(0, text.LastIndexOf(Environment.NewLine, StringComparison.OrdinalIgnoreCase));
- }
-
- _logger.Log(GetLogLevel(severity), text);
- }
-
- /// <summary>
- /// Gets the log level.
- /// </summary>
- /// <param name="severity">The severity.</param>
- /// <returns>NLog.LogLevel.</returns>
- private NLog.LogLevel GetLogLevel(LogSeverity severity)
- {
- switch (severity)
- {
- case LogSeverity.Debug:
- return NLog.LogLevel.Debug;
- case LogSeverity.Error:
- return NLog.LogLevel.Error;
- case LogSeverity.Warn:
- return NLog.LogLevel.Warn;
- case LogSeverity.Fatal:
- return NLog.LogLevel.Fatal;
- case LogSeverity.Info:
- return NLog.LogLevel.Info;
- default:
- throw new ArgumentException("Unknown LogSeverity: " + severity.ToString());
- }
- }
-
- /// <summary>
- /// Logs the specified severity.
- /// </summary>
- /// <param name="severity">The severity.</param>
- /// <param name="message">The message.</param>
- /// <param name="paramList">The param list.</param>
- public void Log(LogSeverity severity, string message, params object[] paramList)
- {
- _logger.Log(GetLogLevel(severity), message, paramList);
- }
-
- /// <summary>
- /// Fatals the specified message.
- /// </summary>
- /// <param name="message">The message.</param>
- /// <param name="paramList">The param list.</param>
- public void Fatal(string message, params object[] paramList)
- {
- _logger.Fatal(message, paramList);
- }
-
- /// <summary>
- /// Fatals the exception.
- /// </summary>
- /// <param name="message">The message.</param>
- /// <param name="exception">The exception.</param>
- /// <param name="paramList">The param list.</param>
- public void FatalException(string message, Exception exception, params object[] paramList)
- {
- LogException(LogSeverity.Fatal, message, exception, paramList);
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Logging/NlogManager.cs b/MediaBrowser.Common.Implementations/Logging/NlogManager.cs
deleted file mode 100644
index 1bbcccd884..0000000000
--- a/MediaBrowser.Common.Implementations/Logging/NlogManager.cs
+++ /dev/null
@@ -1,264 +0,0 @@
-using MediaBrowser.Model.Logging;
-using NLog;
-using NLog.Config;
-using NLog.Targets;
-using NLog.Targets.Wrappers;
-using System;
-using System.IO;
-using System.Linq;
-
-namespace MediaBrowser.Common.Implementations.Logging
-{
- /// <summary>
- /// Class NlogManager
- /// </summary>
- public class NlogManager : ILogManager
- {
- /// <summary>
- /// Occurs when [logger loaded].
- /// </summary>
- public event EventHandler LoggerLoaded;
- /// <summary>
- /// Gets or sets the log directory.
- /// </summary>
- /// <value>The log directory.</value>
- private string LogDirectory { get; set; }
- /// <summary>
- /// Gets or sets the log file prefix.
- /// </summary>
- /// <value>The log file prefix.</value>
- private string LogFilePrefix { get; set; }
- /// <summary>
- /// Gets the log file path.
- /// </summary>
- /// <value>The log file path.</value>
- public string LogFilePath { get; private set; }
-
- /// <summary>
- /// Gets or sets the exception message prefix.
- /// </summary>
- /// <value>The exception message prefix.</value>
- public string ExceptionMessagePrefix { get; set; }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="NlogManager" /> class.
- /// </summary>
- /// <param name="logDirectory">The log directory.</param>
- /// <param name="logFileNamePrefix">The log file name prefix.</param>
- public NlogManager(string logDirectory, string logFileNamePrefix)
- {
- LogDirectory = logDirectory;
- LogFilePrefix = logFileNamePrefix;
-
- LogManager.Configuration = new LoggingConfiguration ();
- }
-
- private LogSeverity _severity = LogSeverity.Debug;
- public LogSeverity LogSeverity
- {
- get
- {
- return _severity;
- }
- set
- {
- var changed = _severity != value;
-
- _severity = value;
-
- if (changed)
- {
- UpdateLogLevel(value);
- }
- }
- }
-
- private void UpdateLogLevel(LogSeverity newLevel)
- {
- var level = GetLogLevel(newLevel);
-
- var rules = LogManager.Configuration.LoggingRules;
-
- foreach (var rule in rules)
- {
- if (!rule.IsLoggingEnabledForLevel(level))
- {
- rule.EnableLoggingForLevel(level);
- }
- foreach (var lev in rule.Levels.ToArray())
- {
- if (lev < level)
- {
- rule.DisableLoggingForLevel(lev);
- }
- }
- }
- }
-
- /// <summary>
- /// Adds the file target.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <param name="level">The level.</param>
- private void AddFileTarget(string path, LogSeverity level)
- {
- RemoveTarget("ApplicationLogFileWrapper");
-
- var wrapper = new AsyncTargetWrapper ();
- wrapper.Name = "ApplicationLogFileWrapper";
-
- var logFile = new FileTarget
- {
- FileName = path,
- Layout = "${longdate} ${level} ${logger}: ${message}"
- };
-
- logFile.Name = "ApplicationLogFile";
-
- wrapper.WrappedTarget = logFile;
-
- AddLogTarget(wrapper, level);
- }
-
- /// <summary>
- /// Adds the log target.
- /// </summary>
- /// <param name="target">The target.</param>
- /// <param name="level">The level.</param>
- public void AddLogTarget(Target target, LogSeverity level)
- {
- var config = LogManager.Configuration;
- config.AddTarget(target.Name, target);
-
- var rule = new LoggingRule("*", GetLogLevel(level), target);
- config.LoggingRules.Add(rule);
-
- LogManager.Configuration = config;
- }
-
- /// <summary>
- /// Removes the target.
- /// </summary>
- /// <param name="name">The name.</param>
- public void RemoveTarget(string name)
- {
- var config = LogManager.Configuration;
-
- var target = config.FindTargetByName(name);
-
- if (target != null)
- {
- foreach (var rule in config.LoggingRules.ToList())
- {
- var contains = rule.Targets.Contains(target);
-
- rule.Targets.Remove(target);
-
- if (contains)
- {
- config.LoggingRules.Remove(rule);
- }
- }
-
- config.RemoveTarget(name);
- LogManager.Configuration = config;
- }
- }
-
- /// <summary>
- /// Gets the logger.
- /// </summary>
- /// <param name="name">The name.</param>
- /// <returns>ILogger.</returns>
- public Model.Logging.ILogger GetLogger(string name)
- {
- return new NLogger(name, this);
- }
-
- /// <summary>
- /// Gets the log level.
- /// </summary>
- /// <param name="severity">The severity.</param>
- /// <returns>LogLevel.</returns>
- /// <exception cref="System.ArgumentException">Unrecognized LogSeverity</exception>
- private LogLevel GetLogLevel(LogSeverity severity)
- {
- switch (severity)
- {
- case LogSeverity.Debug:
- return LogLevel.Debug;
- case LogSeverity.Error:
- return LogLevel.Error;
- case LogSeverity.Fatal:
- return LogLevel.Fatal;
- case LogSeverity.Info:
- return LogLevel.Info;
- case LogSeverity.Warn:
- return LogLevel.Warn;
- default:
- throw new ArgumentException("Unrecognized LogSeverity");
- }
- }
-
- /// <summary>
- /// Reloads the logger.
- /// </summary>
- /// <param name="level">The level.</param>
- public void ReloadLogger(LogSeverity level)
- {
- LogFilePath = Path.Combine(LogDirectory, LogFilePrefix + "-" + decimal.Round(DateTime.Now.Ticks / 10000000) + ".txt");
-
- Directory.CreateDirectory(Path.GetDirectoryName(LogFilePath));
-
- AddFileTarget(LogFilePath, level);
-
- LogSeverity = level;
-
- if (LoggerLoaded != null)
- {
- try
- {
- LoggerLoaded(this, EventArgs.Empty);
- }
- catch (Exception ex)
- {
- GetLogger("Logger").ErrorException("Error in LoggerLoaded event", ex);
- }
- }
- }
-
- /// <summary>
- /// Flushes this instance.
- /// </summary>
- public void Flush()
- {
- LogManager.Flush();
- }
-
-
- public void AddConsoleOutput()
- {
- RemoveTarget("ConsoleTargetWrapper");
-
- var wrapper = new AsyncTargetWrapper ();
- wrapper.Name = "ConsoleTargetWrapper";
-
- var target = new ConsoleTarget()
- {
- Layout = "${level}, ${logger}, ${message}",
- Error = false
- };
-
- target.Name = "ConsoleTarget";
-
- wrapper.WrappedTarget = target;
-
- AddLogTarget(wrapper, LogSeverity);
- }
-
- public void RemoveConsoleOutput()
- {
- RemoveTarget("ConsoleTargetWrapper");
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
deleted file mode 100644
index ce776b2452..0000000000
--- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
+++ /dev/null
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.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>
- <FileAlignment>512</FileAlignment>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
- <ProductVersion>10.0.0</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
- <TargetFrameworkProfile />
- </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>none</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release Mono|AnyCPU' ">
- <DebugType>none</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release Mono\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup>
- <RunPostBuildEvent>Always</RunPostBuildEvent>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
- <HintPath>..\packages\NLog.4.3.10\lib\net45\NLog.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Patterns.Logging">
- <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
- </Reference>
- <Reference Include="SimpleInjector, Version=3.2.4.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
- <HintPath>..\packages\SimpleInjector.3.2.4\lib\net45\SimpleInjector.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Configuration" />
- <Reference Include="System.Core" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Net" />
- <Reference Include="System.Xml" />
- <Reference Include="ServiceStack.Text">
- <HintPath>..\ThirdParty\ServiceStack.Text\ServiceStack.Text.dll</HintPath>
- </Reference>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="..\SharedVersion.cs">
- <Link>Properties\SharedVersion.cs</Link>
- </Compile>
- <Compile Include="BaseApplicationHost.cs" />
- <Compile Include="BaseApplicationPaths.cs" />
- <Compile Include="Configuration\BaseConfigurationManager.cs" />
- <Compile Include="Configuration\ConfigurationHelper.cs" />
- <Compile Include="Cryptography\CryptographyProvider.cs" />
- <Compile Include="Devices\DeviceId.cs" />
- <Compile Include="HttpClientManager\HttpClientInfo.cs" />
- <Compile Include="HttpClientManager\HttpClientManager.cs" />
- <Compile Include="IO\IsoManager.cs" />
- <Compile Include="IO\LnkShortcutHandler.cs" />
- <Compile Include="IO\ManagedFileSystem.cs" />
- <Compile Include="IO\WindowsFileSystem.cs" />
- <Compile Include="Logging\LogHelper.cs" />
- <Compile Include="Logging\NLogger.cs" />
- <Compile Include="Logging\NlogManager.cs" />
- <Compile Include="Networking\BaseNetworkManager.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="ScheduledTasks\DailyTrigger.cs" />
- <Compile Include="ScheduledTasks\IntervalTrigger.cs" />
- <Compile Include="ScheduledTasks\ScheduledTaskWorker.cs" />
- <Compile Include="ScheduledTasks\StartupTrigger.cs" />
- <Compile Include="ScheduledTasks\SystemEventTrigger.cs" />
- <Compile Include="ScheduledTasks\TaskManager.cs" />
- <Compile Include="ScheduledTasks\Tasks\DeleteCacheFileTask.cs" />
- <Compile Include="ScheduledTasks\Tasks\DeleteLogFileTask.cs" />
- <Compile Include="ScheduledTasks\Tasks\ReloadLoggerFileTask.cs" />
- <Compile Include="ScheduledTasks\WeeklyTrigger.cs" />
- <Compile Include="Security\MbAdmin.cs" />
- <Compile Include="Security\MBLicenseFile.cs" />
- <Compile Include="Security\PluginSecurityManager.cs" />
- <Compile Include="Security\RegRecord.cs" />
- <Compile Include="Security\SuppporterInfoResponse.cs" />
- <Compile Include="Serialization\JsonSerializer.cs" />
- <Compile Include="Serialization\XmlSerializer.cs" />
- <Compile Include="Updates\GithubUpdater.cs" />
- <Compile Include="Updates\InstallationManager.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>
- <ItemGroup />
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <PropertyGroup>
- <PostBuildEvent />
- </PropertyGroup>
- <PropertyGroup>
- <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">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
deleted file mode 100644
index 5e00514d55..0000000000
--- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
+++ /dev/null
@@ -1,385 +0,0 @@
-using MediaBrowser.Model.Logging;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Net;
-using System.Net.NetworkInformation;
-using System.Net.Sockets;
-using MediaBrowser.Model.Extensions;
-
-namespace MediaBrowser.Common.Implementations.Networking
-{
- public abstract class BaseNetworkManager
- {
- protected ILogger Logger { get; private set; }
- private DateTime _lastRefresh;
-
- protected BaseNetworkManager(ILogger logger)
- {
- Logger = logger;
- }
-
- private List<IPAddress> _localIpAddresses;
- private readonly object _localIpAddressSyncLock = new object();
-
- /// <summary>
- /// Gets the machine's local ip address
- /// </summary>
- /// <returns>IPAddress.</returns>
- public IEnumerable<IPAddress> GetLocalIpAddresses()
- {
- const int cacheMinutes = 5;
-
- lock (_localIpAddressSyncLock)
- {
- var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
-
- if (_localIpAddresses == null || forceRefresh)
- {
- var addresses = GetLocalIpAddressesInternal().ToList();
-
- _localIpAddresses = addresses;
- _lastRefresh = DateTime.UtcNow;
-
- return addresses;
- }
- }
-
- return _localIpAddresses;
- }
-
- private IEnumerable<IPAddress> GetLocalIpAddressesInternal()
- {
- var list = GetIPsDefault()
- .ToList();
-
- if (list.Count == 0)
- {
- list.AddRange(GetLocalIpAddressesFallback());
- }
-
- return list.Where(FilterIpAddress).DistinctBy(i => i.ToString());
- }
-
- private bool FilterIpAddress(IPAddress address)
- {
- var addressString = address.ToString ();
-
- if (addressString.StartsWith("169.", StringComparison.OrdinalIgnoreCase))
- {
- return false;
- }
-
- return true;
- }
-
- public bool IsInPrivateAddressSpace(string endpoint)
- {
- if (string.Equals(endpoint, "::1", StringComparison.OrdinalIgnoreCase))
- {
- return true;
- }
-
- // Handle ipv4 mapped to ipv6
- endpoint = endpoint.Replace("::ffff:", string.Empty);
-
- // Private address space:
- // http://en.wikipedia.org/wiki/Private_network
-
- if (endpoint.StartsWith("172.", StringComparison.OrdinalIgnoreCase))
- {
- return Is172AddressPrivate(endpoint);
- }
-
- return
-
- endpoint.StartsWith("localhost", StringComparison.OrdinalIgnoreCase) ||
- endpoint.StartsWith("127.", StringComparison.OrdinalIgnoreCase) ||
- endpoint.StartsWith("10.", StringComparison.OrdinalIgnoreCase) ||
- endpoint.StartsWith("192.168", StringComparison.OrdinalIgnoreCase) ||
- endpoint.StartsWith("169.", StringComparison.OrdinalIgnoreCase);
- }
-
- private bool Is172AddressPrivate(string endpoint)
- {
- for (var i = 16; i <= 31; i++)
- {
- if (endpoint.StartsWith("172." + i.ToString(CultureInfo.InvariantCulture) + ".", StringComparison.OrdinalIgnoreCase))
- {
- return true;
- }
- }
-
- return false;
- }
-
- public bool IsInLocalNetwork(string endpoint)
- {
- return IsInLocalNetworkInternal(endpoint, true);
- }
-
- public bool IsInLocalNetworkInternal(string endpoint, bool resolveHost)
- {
- if (string.IsNullOrWhiteSpace(endpoint))
- {
- throw new ArgumentNullException("endpoint");
- }
-
- IPAddress address;
- if (IPAddress.TryParse(endpoint, out address))
- {
- var addressString = address.ToString();
-
- int lengthMatch = 100;
- if (address.AddressFamily == AddressFamily.InterNetwork)
- {
- lengthMatch = 4;
- if (IsInPrivateAddressSpace(addressString))
- {
- return true;
- }
- }
- else if (address.AddressFamily == AddressFamily.InterNetworkV6)
- {
- lengthMatch = 10;
- if (IsInPrivateAddressSpace(endpoint))
- {
- return true;
- }
- }
-
- // Should be even be doing this with ipv6?
- if (addressString.Length >= lengthMatch)
- {
- var prefix = addressString.Substring(0, lengthMatch);
-
- if (GetLocalIpAddresses().Any(i => i.ToString().StartsWith(prefix, StringComparison.OrdinalIgnoreCase)))
- {
- return true;
- }
- }
- }
- else if (resolveHost)
- {
- Uri uri;
- if (Uri.TryCreate(endpoint, UriKind.RelativeOrAbsolute, out uri))
- {
- try
- {
- var host = uri.DnsSafeHost;
- Logger.Debug("Resolving host {0}", host);
-
- address = GetIpAddresses(host).FirstOrDefault();
-
- if (address != null)
- {
- Logger.Debug("{0} resolved to {1}", host, address);
-
- return IsInLocalNetworkInternal(address.ToString(), false);
- }
- }
- catch (InvalidOperationException)
- {
- // Can happen with reverse proxy or IIS url rewriting
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error resovling hostname", ex);
- }
- }
- }
-
- return false;
- }
-
- public IEnumerable<IPAddress> GetIpAddresses(string hostName)
- {
- return Dns.GetHostAddresses(hostName);
- }
-
- private List<IPAddress> GetIPsDefault()
- {
- NetworkInterface[] interfaces;
-
- try
- {
- interfaces = NetworkInterface.GetAllNetworkInterfaces();
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error in GetAllNetworkInterfaces", ex);
- return new List<IPAddress>();
- }
-
- return interfaces.SelectMany(network => {
-
- try
- {
- Logger.Debug("Querying interface: {0}. Type: {1}. Status: {2}", network.Name, network.NetworkInterfaceType, network.OperationalStatus);
-
- var properties = network.GetIPProperties();
-
- return properties.UnicastAddresses
- .Where(i => i.IsDnsEligible)
- .Select(i => i.Address)
- .Where(i => i.AddressFamily == AddressFamily.InterNetwork)
- .ToList();
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error querying network interface", ex);
- return new List<IPAddress>();
- }
-
- }).DistinctBy(i => i.ToString())
- .ToList();
- }
-
- private IEnumerable<IPAddress> GetLocalIpAddressesFallback()
- {
- var host = Dns.GetHostEntry(Dns.GetHostName());
-
- // Reverse them because the last one is usually the correct one
- // It's not fool-proof so ultimately the consumer will have to examine them and decide
- return host.AddressList
- .Where(i => i.AddressFamily == AddressFamily.InterNetwork)
- .Reverse();
- }
-
- /// <summary>
- /// Gets a random port number that is currently available
- /// </summary>
- /// <returns>System.Int32.</returns>
- public int GetRandomUnusedPort()
- {
- var listener = new TcpListener(IPAddress.Any, 0);
- listener.Start();
- var port = ((IPEndPoint)listener.LocalEndpoint).Port;
- listener.Stop();
- return port;
- }
-
- /// <summary>
- /// Returns MAC Address from first Network Card in Computer
- /// </summary>
- /// <returns>[string] MAC Address</returns>
- public string GetMacAddress()
- {
- return NetworkInterface.GetAllNetworkInterfaces()
- .Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback)
- .Select(i => BitConverter.ToString(i.GetPhysicalAddress().GetAddressBytes()))
- .FirstOrDefault();
- }
-
- /// <summary>
- /// Parses the specified endpointstring.
- /// </summary>
- /// <param name="endpointstring">The endpointstring.</param>
- /// <returns>IPEndPoint.</returns>
- public IPEndPoint Parse(string endpointstring)
- {
- return Parse(endpointstring, -1);
- }
-
- /// <summary>
- /// Parses the specified endpointstring.
- /// </summary>
- /// <param name="endpointstring">The endpointstring.</param>
- /// <param name="defaultport">The defaultport.</param>
- /// <returns>IPEndPoint.</returns>
- /// <exception cref="System.ArgumentException">Endpoint descriptor may not be empty.</exception>
- /// <exception cref="System.FormatException"></exception>
- private static IPEndPoint Parse(string endpointstring, int defaultport)
- {
- if (String.IsNullOrEmpty(endpointstring)
- || endpointstring.Trim().Length == 0)
- {
- throw new ArgumentException("Endpoint descriptor may not be empty.");
- }
-
- if (defaultport != -1 &&
- (defaultport < IPEndPoint.MinPort
- || defaultport > IPEndPoint.MaxPort))
- {
- throw new ArgumentException(String.Format("Invalid default port '{0}'", defaultport));
- }
-
- string[] values = endpointstring.Split(new char[] { ':' });
- IPAddress ipaddy;
- int port = -1;
-
- //check if we have an IPv6 or ports
- if (values.Length <= 2) // ipv4 or hostname
- {
- port = values.Length == 1 ? defaultport : GetPort(values[1]);
-
- //try to use the address as IPv4, otherwise get hostname
- if (!IPAddress.TryParse(values[0], out ipaddy))
- ipaddy = GetIPfromHost(values[0]);
- }
- else if (values.Length > 2) //ipv6
- {
- //could [a:b:c]:d
- if (values[0].StartsWith("[") && values[values.Length - 2].EndsWith("]"))
- {
- string ipaddressstring = String.Join(":", values.Take(values.Length - 1).ToArray());
- ipaddy = IPAddress.Parse(ipaddressstring);
- port = GetPort(values[values.Length - 1]);
- }
- else //[a:b:c] or a:b:c
- {
- ipaddy = IPAddress.Parse(endpointstring);
- port = defaultport;
- }
- }
- else
- {
- throw new FormatException(String.Format("Invalid endpoint ipaddress '{0}'", endpointstring));
- }
-
- if (port == -1)
- throw new ArgumentException(String.Format("No port specified: '{0}'", endpointstring));
-
- return new IPEndPoint(ipaddy, port);
- }
-
- protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
- /// <summary>
- /// Gets the port.
- /// </summary>
- /// <param name="p">The p.</param>
- /// <returns>System.Int32.</returns>
- /// <exception cref="System.FormatException"></exception>
- private static int GetPort(string p)
- {
- int port;
-
- if (!Int32.TryParse(p, out port)
- || port < IPEndPoint.MinPort
- || port > IPEndPoint.MaxPort)
- {
- throw new FormatException(String.Format("Invalid end point port '{0}'", p));
- }
-
- return port;
- }
-
- /// <summary>
- /// Gets the I pfrom host.
- /// </summary>
- /// <param name="p">The p.</param>
- /// <returns>IPAddress.</returns>
- /// <exception cref="System.ArgumentException"></exception>
- private static IPAddress GetIPfromHost(string p)
- {
- var hosts = Dns.GetHostAddresses(p);
-
- if (hosts == null || hosts.Length == 0)
- throw new ArgumentException(String.Format("Host not found: {0}", p));
-
- return hosts[0];
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Properties/AssemblyInfo.cs b/MediaBrowser.Common.Implementations/Properties/AssemblyInfo.cs
deleted file mode 100644
index 63a83e0034..0000000000
--- a/MediaBrowser.Common.Implementations/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("MediaBrowser.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/DailyTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/DailyTrigger.cs
deleted file mode 100644
index 3d33e958de..0000000000
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/DailyTrigger.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-using MediaBrowser.Model.Events;
-using MediaBrowser.Model.Tasks;
-using System;
-using System.Globalization;
-using System.Threading;
-using MediaBrowser.Model.Logging;
-
-namespace MediaBrowser.Common.ScheduledTasks
-{
- /// <summary>
- /// Represents a task trigger that fires everyday
- /// </summary>
- public class DailyTrigger : ITaskTrigger
- {
- /// <summary>
- /// Get the time of day to trigger the task to run
- /// </summary>
- /// <value>The time of day.</value>
- public TimeSpan TimeOfDay { get; set; }
-
- /// <summary>
- /// Gets or sets the timer.
- /// </summary>
- /// <value>The timer.</value>
- private Timer Timer { get; set; }
-
- /// <summary>
- /// Gets the execution properties of this task.
- /// </summary>
- /// <value>
- /// The execution properties of this task.
- /// </value>
- public TaskExecutionOptions TaskOptions { get; set; }
-
- /// <summary>
- /// Stars waiting for the trigger action
- /// </summary>
- /// <param name="lastResult">The last result.</param>
- /// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
- public void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup)
- {
- DisposeTimer();
-
- var now = DateTime.Now;
-
- var triggerDate = now.TimeOfDay > TimeOfDay ? now.Date.AddDays(1) : now.Date;
- triggerDate = triggerDate.Add(TimeOfDay);
-
- var dueTime = triggerDate - now;
-
- logger.Info("Daily trigger for {0} set to fire at {1}, which is {2} minutes from now.", taskName, triggerDate.ToString(), dueTime.TotalMinutes.ToString(CultureInfo.InvariantCulture));
-
- Timer = new Timer(state => OnTriggered(), null, dueTime, TimeSpan.FromMilliseconds(-1));
- }
-
- /// <summary>
- /// Stops waiting for the trigger action
- /// </summary>
- public void Stop()
- {
- DisposeTimer();
- }
-
- /// <summary>
- /// Disposes the timer.
- /// </summary>
- private void DisposeTimer()
- {
- if (Timer != null)
- {
- Timer.Dispose();
- }
- }
-
- /// <summary>
- /// Occurs when [triggered].
- /// </summary>
- public event EventHandler<GenericEventArgs<TaskExecutionOptions>> Triggered;
-
- /// <summary>
- /// Called when [triggered].
- /// </summary>
- private void OnTriggered()
- {
- if (Triggered != null)
- {
- Triggered(this, new GenericEventArgs<TaskExecutionOptions>(TaskOptions));
- }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/IntervalTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/IntervalTrigger.cs
deleted file mode 100644
index 8038d5551d..0000000000
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/IntervalTrigger.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-using MediaBrowser.Model.Events;
-using MediaBrowser.Model.Tasks;
-using System;
-using System.Linq;
-using System.Threading;
-using MediaBrowser.Model.Logging;
-
-namespace MediaBrowser.Common.ScheduledTasks
-{
- /// <summary>
- /// Represents a task trigger that runs repeatedly on an interval
- /// </summary>
- public class IntervalTrigger : ITaskTrigger
- {
- /// <summary>
- /// Gets or sets the interval.
- /// </summary>
- /// <value>The interval.</value>
- public TimeSpan Interval { get; set; }
-
- /// <summary>
- /// Gets or sets the timer.
- /// </summary>
- /// <value>The timer.</value>
- private Timer Timer { get; set; }
-
- /// <summary>
- /// Gets the execution properties of this task.
- /// </summary>
- /// <value>
- /// The execution properties of this task.
- /// </value>
- public TaskExecutionOptions TaskOptions { get; set; }
-
- private DateTime _lastStartDate;
-
- /// <summary>
- /// Stars waiting for the trigger action
- /// </summary>
- /// <param name="lastResult">The last result.</param>
- /// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
- public void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup)
- {
- DisposeTimer();
-
- DateTime triggerDate;
-
- if (lastResult == null)
- {
- // Task has never been completed before
- triggerDate = DateTime.UtcNow.AddHours(1);
- }
- else
- {
- triggerDate = new[] { lastResult.EndTimeUtc, _lastStartDate }.Max().Add(Interval);
- }
-
- if (DateTime.UtcNow > triggerDate)
- {
- triggerDate = DateTime.UtcNow.AddMinutes(1);
- }
-
- var dueTime = triggerDate - DateTime.UtcNow;
- var maxDueTime = TimeSpan.FromDays(7);
-
- if (dueTime > maxDueTime)
- {
- dueTime = maxDueTime;
- }
-
- Timer = new Timer(state => OnTriggered(), null, dueTime, TimeSpan.FromMilliseconds(-1));
- }
-
- /// <summary>
- /// Stops waiting for the trigger action
- /// </summary>
- public void Stop()
- {
- DisposeTimer();
- }
-
- /// <summary>
- /// Disposes the timer.
- /// </summary>
- private void DisposeTimer()
- {
- if (Timer != null)
- {
- Timer.Dispose();
- }
- }
-
- /// <summary>
- /// Occurs when [triggered].
- /// </summary>
- public event EventHandler<GenericEventArgs<TaskExecutionOptions>> Triggered;
-
- /// <summary>
- /// Called when [triggered].
- /// </summary>
- private void OnTriggered()
- {
- DisposeTimer();
-
- if (Triggered != null)
- {
- _lastStartDate = DateTime.UtcNow;
- Triggered(this, new GenericEventArgs<TaskExecutionOptions>(TaskOptions));
- }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
deleted file mode 100644
index 0d99283c3d..0000000000
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
+++ /dev/null
@@ -1,781 +0,0 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Events;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.ScheduledTasks;
-using MediaBrowser.Model.Events;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Tasks;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.IO;
-
-namespace MediaBrowser.Common.Implementations.ScheduledTasks
-{
- /// <summary>
- /// Class ScheduledTaskWorker
- /// </summary>
- public class ScheduledTaskWorker : IScheduledTaskWorker
- {
- public event EventHandler<GenericEventArgs<double>> TaskProgress;
-
- /// <summary>
- /// Gets or sets the scheduled task.
- /// </summary>
- /// <value>The scheduled task.</value>
- public IScheduledTask ScheduledTask { get; private set; }
-
- /// <summary>
- /// Gets or sets the json serializer.
- /// </summary>
- /// <value>The json serializer.</value>
- private IJsonSerializer JsonSerializer { get; set; }
-
- /// <summary>
- /// Gets or sets the application paths.
- /// </summary>
- /// <value>The application paths.</value>
- private IApplicationPaths ApplicationPaths { get; set; }
-
- /// <summary>
- /// Gets the logger.
- /// </summary>
- /// <value>The logger.</value>
- private ILogger Logger { get; set; }
-
- /// <summary>
- /// Gets the task manager.
- /// </summary>
- /// <value>The task manager.</value>
- private ITaskManager TaskManager { get; set; }
- private readonly IFileSystem _fileSystem;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="ScheduledTaskWorker" /> class.
- /// </summary>
- /// <param name="scheduledTask">The scheduled task.</param>
- /// <param name="applicationPaths">The application paths.</param>
- /// <param name="taskManager">The task manager.</param>
- /// <param name="jsonSerializer">The json serializer.</param>
- /// <param name="logger">The logger.</param>
- /// <exception cref="System.ArgumentNullException">
- /// scheduledTask
- /// or
- /// applicationPaths
- /// or
- /// taskManager
- /// or
- /// jsonSerializer
- /// or
- /// logger
- /// </exception>
- public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, IJsonSerializer jsonSerializer, ILogger logger, IFileSystem fileSystem)
- {
- if (scheduledTask == null)
- {
- throw new ArgumentNullException("scheduledTask");
- }
- if (applicationPaths == null)
- {
- throw new ArgumentNullException("applicationPaths");
- }
- if (taskManager == null)
- {
- throw new ArgumentNullException("taskManager");
- }
- if (jsonSerializer == null)
- {
- throw new ArgumentNullException("jsonSerializer");
- }
- if (logger == null)
- {
- throw new ArgumentNullException("logger");
- }
-
- ScheduledTask = scheduledTask;
- ApplicationPaths = applicationPaths;
- TaskManager = taskManager;
- JsonSerializer = jsonSerializer;
- Logger = logger;
- _fileSystem = fileSystem;
-
- InitTriggerEvents();
- }
-
- private bool _readFromFile = false;
- /// <summary>
- /// The _last execution result
- /// </summary>
- private TaskResult _lastExecutionResult;
- /// <summary>
- /// The _last execution result sync lock
- /// </summary>
- private readonly object _lastExecutionResultSyncLock = new object();
- /// <summary>
- /// Gets the last execution result.
- /// </summary>
- /// <value>The last execution result.</value>
- public TaskResult LastExecutionResult
- {
- get
- {
- var path = GetHistoryFilePath();
-
- lock (_lastExecutionResultSyncLock)
- {
- if (_lastExecutionResult == null && !_readFromFile)
- {
- try
- {
- _lastExecutionResult = JsonSerializer.DeserializeFromFile<TaskResult>(path);
- }
- catch (DirectoryNotFoundException)
- {
- // File doesn't exist. No biggie
- }
- catch (FileNotFoundException)
- {
- // File doesn't exist. No biggie
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error deserializing {0}", ex, path);
- }
- _readFromFile = true;
- }
- }
-
- return _lastExecutionResult;
- }
- private set
- {
- _lastExecutionResult = value;
-
- var path = GetHistoryFilePath();
- _fileSystem.CreateDirectory(Path.GetDirectoryName(path));
-
- lock (_lastExecutionResultSyncLock)
- {
- JsonSerializer.SerializeToFile(value, path);
- }
- }
- }
-
- /// <summary>
- /// Gets the name.
- /// </summary>
- /// <value>The name.</value>
- public string Name
- {
- get { return ScheduledTask.Name; }
- }
-
- /// <summary>
- /// Gets the description.
- /// </summary>
- /// <value>The description.</value>
- public string Description
- {
- get { return ScheduledTask.Description; }
- }
-
- /// <summary>
- /// Gets the category.
- /// </summary>
- /// <value>The category.</value>
- public string Category
- {
- get { return ScheduledTask.Category; }
- }
-
- /// <summary>
- /// Gets the current cancellation token
- /// </summary>
- /// <value>The current cancellation token source.</value>
- private CancellationTokenSource CurrentCancellationTokenSource { get; set; }
-
- /// <summary>
- /// Gets or sets the current execution start time.
- /// </summary>
- /// <value>The current execution start time.</value>
- private DateTime CurrentExecutionStartTime { get; set; }
-
- /// <summary>
- /// Gets the state.
- /// </summary>
- /// <value>The state.</value>
- public TaskState State
- {
- get
- {
- if (CurrentCancellationTokenSource != null)
- {
- return CurrentCancellationTokenSource.IsCancellationRequested
- ? TaskState.Cancelling
- : TaskState.Running;
- }
-
- return TaskState.Idle;
- }
- }
-
- /// <summary>
- /// Gets the current progress.
- /// </summary>
- /// <value>The current progress.</value>
- public double? CurrentProgress { get; private set; }
-
- /// <summary>
- /// The _triggers
- /// </summary>
- private Tuple<TaskTriggerInfo,ITaskTrigger>[] _triggers;
- /// <summary>
- /// Gets the triggers that define when the task will run
- /// </summary>
- /// <value>The triggers.</value>
- private Tuple<TaskTriggerInfo, ITaskTrigger>[] InternalTriggers
- {
- get
- {
- return _triggers;
- }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- // Cleanup current triggers
- if (_triggers != null)
- {
- DisposeTriggers();
- }
-
- _triggers = value.ToArray();
-
- ReloadTriggerEvents(false);
- }
- }
-
- /// <summary>
- /// Gets the triggers that define when the task will run
- /// </summary>
- /// <value>The triggers.</value>
- /// <exception cref="System.ArgumentNullException">value</exception>
- public TaskTriggerInfo[] Triggers
- {
- get
- {
- return InternalTriggers.Select(i => i.Item1).ToArray();
- }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- SaveTriggers(value);
-
- InternalTriggers = value.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray();
- }
- }
-
- /// <summary>
- /// The _id
- /// </summary>
- private string _id;
-
- /// <summary>
- /// Gets the unique id.
- /// </summary>
- /// <value>The unique id.</value>
- public string Id
- {
- get
- {
- if (_id == null)
- {
- _id = ScheduledTask.GetType().FullName.GetMD5().ToString("N");
- }
-
- return _id;
- }
- }
-
- private void InitTriggerEvents()
- {
- _triggers = LoadTriggers();
- ReloadTriggerEvents(true);
- }
-
- public void ReloadTriggerEvents()
- {
- ReloadTriggerEvents(false);
- }
-
- /// <summary>
- /// Reloads the trigger events.
- /// </summary>
- /// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
- private void ReloadTriggerEvents(bool isApplicationStartup)
- {
- foreach (var triggerInfo in InternalTriggers)
- {
- var trigger = triggerInfo.Item2;
-
- trigger.Stop();
-
- trigger.Triggered -= trigger_Triggered;
- trigger.Triggered += trigger_Triggered;
- trigger.Start(LastExecutionResult, Logger, Name, isApplicationStartup);
- }
- }
-
- /// <summary>
- /// Handles the Triggered event of the trigger control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
- async void trigger_Triggered(object sender, GenericEventArgs<TaskExecutionOptions> e)
- {
- var trigger = (ITaskTrigger)sender;
-
- var configurableTask = ScheduledTask as IConfigurableScheduledTask;
-
- if (configurableTask != null && !configurableTask.IsEnabled)
- {
- return;
- }
-
- Logger.Info("{0} fired for task: {1}", trigger.GetType().Name, Name);
-
- trigger.Stop();
-
- TaskManager.QueueScheduledTask(ScheduledTask, e.Argument);
-
- await Task.Delay(1000).ConfigureAwait(false);
-
- trigger.Start(LastExecutionResult, Logger, Name, false);
- }
-
- private Task _currentTask;
-
- /// <summary>
- /// Executes the task
- /// </summary>
- /// <param name="options">Task options.</param>
- /// <returns>Task.</returns>
- /// <exception cref="System.InvalidOperationException">Cannot execute a Task that is already running</exception>
- public async Task Execute(TaskExecutionOptions options)
- {
- var task = ExecuteInternal(options);
-
- _currentTask = task;
-
- try
- {
- await task.ConfigureAwait(false);
- }
- finally
- {
- _currentTask = null;
- }
- }
-
- private async Task ExecuteInternal(TaskExecutionOptions options)
- {
- // Cancel the current execution, if any
- if (CurrentCancellationTokenSource != null)
- {
- throw new InvalidOperationException("Cannot execute a Task that is already running");
- }
-
- var progress = new Progress<double>();
-
- CurrentCancellationTokenSource = new CancellationTokenSource();
-
- Logger.Info("Executing {0}", Name);
-
- ((TaskManager)TaskManager).OnTaskExecuting(this);
-
- progress.ProgressChanged += progress_ProgressChanged;
-
- TaskCompletionStatus status;
- CurrentExecutionStartTime = DateTime.UtcNow;
-
- Exception failureException = null;
-
- try
- {
- if (options != null && options.MaxRuntimeMs.HasValue)
- {
- CurrentCancellationTokenSource.CancelAfter(options.MaxRuntimeMs.Value);
- }
-
- var localTask = ScheduledTask.Execute(CurrentCancellationTokenSource.Token, progress);
-
- await localTask.ConfigureAwait(false);
-
- status = TaskCompletionStatus.Completed;
- }
- catch (OperationCanceledException)
- {
- status = TaskCompletionStatus.Cancelled;
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error", ex);
-
- failureException = ex;
-
- status = TaskCompletionStatus.Failed;
- }
-
- var startTime = CurrentExecutionStartTime;
- var endTime = DateTime.UtcNow;
-
- progress.ProgressChanged -= progress_ProgressChanged;
- CurrentCancellationTokenSource.Dispose();
- CurrentCancellationTokenSource = null;
- CurrentProgress = null;
-
- OnTaskCompleted(startTime, endTime, status, failureException);
- }
-
- /// <summary>
- /// Progress_s the progress changed.
- /// </summary>
- /// <param name="sender">The sender.</param>
- /// <param name="e">The e.</param>
- void progress_ProgressChanged(object sender, double e)
- {
- CurrentProgress = e;
-
- EventHelper.FireEventIfNotNull(TaskProgress, this, new GenericEventArgs<double>
- {
- Argument = e
-
- }, Logger);
- }
-
- /// <summary>
- /// Stops the task if it is currently executing
- /// </summary>
- /// <exception cref="System.InvalidOperationException">Cannot cancel a Task unless it is in the Running state.</exception>
- public void Cancel()
- {
- if (State != TaskState.Running)
- {
- throw new InvalidOperationException("Cannot cancel a Task unless it is in the Running state.");
- }
-
- CancelIfRunning();
- }
-
- /// <summary>
- /// Cancels if running.
- /// </summary>
- public void CancelIfRunning()
- {
- if (State == TaskState.Running)
- {
- Logger.Info("Attempting to cancel Scheduled Task {0}", Name);
- CurrentCancellationTokenSource.Cancel();
- }
- }
-
- /// <summary>
- /// Gets the scheduled tasks configuration directory.
- /// </summary>
- /// <returns>System.String.</returns>
- private string GetScheduledTasksConfigurationDirectory()
- {
- return Path.Combine(ApplicationPaths.ConfigurationDirectoryPath, "ScheduledTasks");
- }
-
- /// <summary>
- /// Gets the scheduled tasks data directory.
- /// </summary>
- /// <returns>System.String.</returns>
- private string GetScheduledTasksDataDirectory()
- {
- return Path.Combine(ApplicationPaths.DataPath, "ScheduledTasks");
- }
-
- /// <summary>
- /// Gets the history file path.
- /// </summary>
- /// <value>The history file path.</value>
- private string GetHistoryFilePath()
- {
- return Path.Combine(GetScheduledTasksDataDirectory(), new Guid(Id) + ".js");
- }
-
- /// <summary>
- /// Gets the configuration file path.
- /// </summary>
- /// <returns>System.String.</returns>
- private string GetConfigurationFilePath()
- {
- return Path.Combine(GetScheduledTasksConfigurationDirectory(), new Guid(Id) + ".js");
- }
-
- /// <summary>
- /// Loads the triggers.
- /// </summary>
- /// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- private Tuple<TaskTriggerInfo, ITaskTrigger>[] LoadTriggers()
- {
- var settings = LoadTriggerSettings();
-
- return settings.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray();
- }
-
- private TaskTriggerInfo[] LoadTriggerSettings()
- {
- try
- {
- return JsonSerializer.DeserializeFromFile<IEnumerable<TaskTriggerInfo>>(GetConfigurationFilePath())
- .ToArray();
- }
- catch (FileNotFoundException)
- {
- // File doesn't exist. No biggie. Return defaults.
- return ScheduledTask.GetDefaultTriggers().ToArray();
- }
- catch (DirectoryNotFoundException)
- {
- // File doesn't exist. No biggie. Return defaults.
- return ScheduledTask.GetDefaultTriggers().ToArray();
- }
- }
-
- /// <summary>
- /// Saves the triggers.
- /// </summary>
- /// <param name="triggers">The triggers.</param>
- private void SaveTriggers(TaskTriggerInfo[] triggers)
- {
- var path = GetConfigurationFilePath();
-
- _fileSystem.CreateDirectory(Path.GetDirectoryName(path));
-
- JsonSerializer.SerializeToFile(triggers, path);
- }
-
- /// <summary>
- /// Called when [task completed].
- /// </summary>
- /// <param name="startTime">The start time.</param>
- /// <param name="endTime">The end time.</param>
- /// <param name="status">The status.</param>
- private void OnTaskCompleted(DateTime startTime, DateTime endTime, TaskCompletionStatus status, Exception ex)
- {
- 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
- };
-
- result.Key = ScheduledTask.Key;
-
- if (ex != null)
- {
- result.ErrorMessage = ex.Message;
- result.LongErrorMessage = ex.StackTrace;
- }
-
- LastExecutionResult = result;
-
- ((TaskManager)TaskManager).OnTaskCompleted(this, result);
- }
-
- /// <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)
- {
- DisposeTriggers();
-
- var wassRunning = State == TaskState.Running;
- var startTime = CurrentExecutionStartTime;
-
- var token = CurrentCancellationTokenSource;
- if (token != null)
- {
- try
- {
- Logger.Info(Name + ": Cancelling");
- token.Cancel();
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error calling CancellationToken.Cancel();", ex);
- }
- }
- var task = _currentTask;
- if (task != null)
- {
- try
- {
- Logger.Info(Name + ": Waiting on Task");
- var exited = Task.WaitAll(new[] { task }, 2000);
-
- if (exited)
- {
- Logger.Info(Name + ": Task exited");
- }
- else
- {
- Logger.Info(Name + ": Timed out waiting for task to stop");
- }
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error calling Task.WaitAll();", ex);
- }
- }
-
- if (token != null)
- {
- try
- {
- Logger.Debug(Name + ": Disposing CancellationToken");
- token.Dispose();
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error calling CancellationToken.Dispose();", ex);
- }
- }
- if (wassRunning)
- {
- OnTaskCompleted(startTime, DateTime.UtcNow, TaskCompletionStatus.Aborted, null);
- }
- }
- }
-
- /// <summary>
- /// Converts a TaskTriggerInfo into a concrete BaseTaskTrigger
- /// </summary>
- /// <param name="info">The info.</param>
- /// <returns>BaseTaskTrigger.</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
- /// <exception cref="System.ArgumentException">Invalid trigger type: + info.Type</exception>
- public static ITaskTrigger GetTrigger(TaskTriggerInfo info)
- {
- var options = new TaskExecutionOptions
- {
- MaxRuntimeMs = info.MaxRuntimeMs
- };
-
- if (info.Type.Equals(typeof(DailyTrigger).Name, StringComparison.OrdinalIgnoreCase))
- {
- if (!info.TimeOfDayTicks.HasValue)
- {
- throw new ArgumentNullException();
- }
-
- return new DailyTrigger
- {
- TimeOfDay = TimeSpan.FromTicks(info.TimeOfDayTicks.Value),
- TaskOptions = options
- };
- }
-
- if (info.Type.Equals(typeof(WeeklyTrigger).Name, StringComparison.OrdinalIgnoreCase))
- {
- if (!info.TimeOfDayTicks.HasValue)
- {
- throw new ArgumentNullException();
- }
-
- if (!info.DayOfWeek.HasValue)
- {
- throw new ArgumentNullException();
- }
-
- return new WeeklyTrigger
- {
- TimeOfDay = TimeSpan.FromTicks(info.TimeOfDayTicks.Value),
- DayOfWeek = info.DayOfWeek.Value,
- TaskOptions = options
- };
- }
-
- if (info.Type.Equals(typeof(IntervalTrigger).Name, StringComparison.OrdinalIgnoreCase))
- {
- if (!info.IntervalTicks.HasValue)
- {
- throw new ArgumentNullException();
- }
-
- return new IntervalTrigger
- {
- Interval = TimeSpan.FromTicks(info.IntervalTicks.Value),
- TaskOptions = options
- };
- }
-
- if (info.Type.Equals(typeof(SystemEventTrigger).Name, StringComparison.OrdinalIgnoreCase))
- {
- if (!info.SystemEvent.HasValue)
- {
- throw new ArgumentNullException();
- }
-
- return new SystemEventTrigger
- {
- SystemEvent = info.SystemEvent.Value,
- TaskOptions = options
- };
- }
-
- if (info.Type.Equals(typeof(StartupTrigger).Name, StringComparison.OrdinalIgnoreCase))
- {
- return new StartupTrigger();
- }
-
- throw new ArgumentException("Unrecognized trigger type: " + info.Type);
- }
-
- /// <summary>
- /// Disposes each trigger
- /// </summary>
- private void DisposeTriggers()
- {
- foreach (var triggerInfo in InternalTriggers)
- {
- var trigger = triggerInfo.Item2;
- trigger.Triggered -= trigger_Triggered;
- trigger.Stop();
- }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/StartupTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/StartupTrigger.cs
deleted file mode 100644
index 41f58a7ad5..0000000000
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/StartupTrigger.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-using MediaBrowser.Model.Events;
-using MediaBrowser.Model.Tasks;
-using System;
-using System.Threading.Tasks;
-using MediaBrowser.Model.Logging;
-
-namespace MediaBrowser.Common.ScheduledTasks
-{
- /// <summary>
- /// Class StartupTaskTrigger
- /// </summary>
- public class StartupTrigger : ITaskTrigger
- {
- public int DelayMs { get; set; }
-
- /// <summary>
- /// Gets the execution properties of this task.
- /// </summary>
- /// <value>
- /// The execution properties of this task.
- /// </value>
- public TaskExecutionOptions TaskOptions { get; set; }
-
- public StartupTrigger()
- {
- DelayMs = 3000;
- }
-
- /// <summary>
- /// Stars waiting for the trigger action
- /// </summary>
- /// <param name="lastResult">The last result.</param>
- /// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
- public async void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup)
- {
- if (isApplicationStartup)
- {
- await Task.Delay(DelayMs).ConfigureAwait(false);
-
- OnTriggered();
- }
- }
-
- /// <summary>
- /// Stops waiting for the trigger action
- /// </summary>
- public void Stop()
- {
- }
-
- /// <summary>
- /// Occurs when [triggered].
- /// </summary>
- public event EventHandler<GenericEventArgs<TaskExecutionOptions>> Triggered;
-
- /// <summary>
- /// Called when [triggered].
- /// </summary>
- private void OnTriggered()
- {
- if (Triggered != null)
- {
- Triggered(this, new GenericEventArgs<TaskExecutionOptions>(TaskOptions));
- }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/SystemEventTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/SystemEventTrigger.cs
deleted file mode 100644
index 9972dc8044..0000000000
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/SystemEventTrigger.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-using MediaBrowser.Model.Events;
-using MediaBrowser.Model.Tasks;
-using Microsoft.Win32;
-using System;
-using System.Threading.Tasks;
-using MediaBrowser.Model.Logging;
-
-namespace MediaBrowser.Common.ScheduledTasks
-{
- /// <summary>
- /// Class SystemEventTrigger
- /// </summary>
- public class SystemEventTrigger : ITaskTrigger
- {
- /// <summary>
- /// Gets or sets the system event.
- /// </summary>
- /// <value>The system event.</value>
- public SystemEvent SystemEvent { get; set; }
-
- /// <summary>
- /// Gets the execution properties of this task.
- /// </summary>
- /// <value>
- /// The execution properties of this task.
- /// </value>
- public TaskExecutionOptions TaskOptions { get; set; }
-
- /// <summary>
- /// Stars waiting for the trigger action
- /// </summary>
- /// <param name="lastResult">The last result.</param>
- /// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
- public void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup)
- {
- switch (SystemEvent)
- {
- case SystemEvent.WakeFromSleep:
- SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
- break;
- }
- }
-
- /// <summary>
- /// Stops waiting for the trigger action
- /// </summary>
- public void Stop()
- {
- SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
- }
-
- /// <summary>
- /// Handles the PowerModeChanged event of the SystemEvents control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="PowerModeChangedEventArgs" /> instance containing the event data.</param>
- async void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
- {
- if (e.Mode == PowerModes.Resume && SystemEvent == SystemEvent.WakeFromSleep)
- {
- // This value is a bit arbitrary, but add a delay to help ensure network connections have been restored before running the task
- await Task.Delay(10000).ConfigureAwait(false);
-
- OnTriggered();
- }
- }
-
- /// <summary>
- /// Occurs when [triggered].
- /// </summary>
- public event EventHandler<GenericEventArgs<TaskExecutionOptions>> Triggered;
-
- /// <summary>
- /// Called when [triggered].
- /// </summary>
- private void OnTriggered()
- {
- if (Triggered != null)
- {
- Triggered(this, new GenericEventArgs<TaskExecutionOptions>(TaskOptions));
- }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs
deleted file mode 100644
index 9a0221deab..0000000000
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs
+++ /dev/null
@@ -1,364 +0,0 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Events;
-using MediaBrowser.Common.ScheduledTasks;
-using MediaBrowser.Model.Events;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Tasks;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.IO;
-using Microsoft.Win32;
-
-namespace MediaBrowser.Common.Implementations.ScheduledTasks
-{
- /// <summary>
- /// Class TaskManager
- /// </summary>
- public class TaskManager : ITaskManager
- {
- public event EventHandler<GenericEventArgs<IScheduledTaskWorker>> TaskExecuting;
- public event EventHandler<TaskCompletionEventArgs> TaskCompleted;
-
- /// <summary>
- /// Gets the list of Scheduled Tasks
- /// </summary>
- /// <value>The scheduled tasks.</value>
- public IScheduledTaskWorker[] ScheduledTasks { get; private set; }
-
- /// <summary>
- /// The _task queue
- /// </summary>
- private readonly ConcurrentQueue<Tuple<Type, TaskExecutionOptions>> _taskQueue =
- new ConcurrentQueue<Tuple<Type, TaskExecutionOptions>>();
-
- /// <summary>
- /// Gets or sets the json serializer.
- /// </summary>
- /// <value>The json serializer.</value>
- private IJsonSerializer JsonSerializer { get; set; }
-
- /// <summary>
- /// Gets or sets the application paths.
- /// </summary>
- /// <value>The application paths.</value>
- private IApplicationPaths ApplicationPaths { get; set; }
-
- /// <summary>
- /// Gets the logger.
- /// </summary>
- /// <value>The logger.</value>
- private ILogger Logger { get; set; }
- private readonly IFileSystem _fileSystem;
-
- private bool _suspendTriggers;
-
- public bool SuspendTriggers
- {
- get { return _suspendTriggers; }
- set
- {
- Logger.Info("Setting SuspendTriggers to {0}", value);
- var executeQueued = _suspendTriggers && !value;
-
- _suspendTriggers = value;
-
- if (executeQueued)
- {
- ExecuteQueuedTasks();
- }
- }
- }
-
- /// <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, IFileSystem fileSystem)
- {
- ApplicationPaths = applicationPaths;
- JsonSerializer = jsonSerializer;
- Logger = logger;
- _fileSystem = fileSystem;
-
- ScheduledTasks = new IScheduledTaskWorker[] { };
- }
-
- private void BindToSystemEvent()
- {
- try
- {
- SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
- }
- catch
- {
-
- }
- }
-
- void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
- {
- foreach (var task in ScheduledTasks)
- {
- task.ReloadTriggerEvents();
- }
- }
-
- /// <summary>
- /// Cancels if running and queue.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="options">Task options.</param>
- public void CancelIfRunningAndQueue<T>(TaskExecutionOptions options)
- where T : IScheduledTask
- {
- var task = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T));
- ((ScheduledTaskWorker)task).CancelIfRunning();
-
- QueueScheduledTask<T>(options);
- }
-
- public void CancelIfRunningAndQueue<T>()
- where T : IScheduledTask
- {
- CancelIfRunningAndQueue<T>(new TaskExecutionOptions());
- }
-
- /// <summary>
- /// Cancels if running
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public void CancelIfRunning<T>()
- where T : IScheduledTask
- {
- var task = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T));
- ((ScheduledTaskWorker)task).CancelIfRunning();
- }
-
- /// <summary>
- /// Queues the scheduled task.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="options">Task options</param>
- public void QueueScheduledTask<T>(TaskExecutionOptions options)
- where T : IScheduledTask
- {
- var scheduledTask = ScheduledTasks.FirstOrDefault(t => t.ScheduledTask.GetType() == typeof(T));
-
- if (scheduledTask == null)
- {
- Logger.Error("Unable to find scheduled task of type {0} in QueueScheduledTask.", typeof(T).Name);
- }
- else
- {
- QueueScheduledTask(scheduledTask, options);
- }
- }
-
- public void QueueScheduledTask<T>()
- where T : IScheduledTask
- {
- QueueScheduledTask<T>(new TaskExecutionOptions());
- }
-
- public void QueueIfNotRunning<T>()
- where T : IScheduledTask
- {
- var task = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T));
-
- if (task.State != TaskState.Running)
- {
- QueueScheduledTask<T>(new TaskExecutionOptions());
- }
- }
-
- public void Execute<T>()
- where T : IScheduledTask
- {
- var scheduledTask = ScheduledTasks.FirstOrDefault(t => t.ScheduledTask.GetType() == typeof(T));
-
- if (scheduledTask == null)
- {
- Logger.Error("Unable to find scheduled task of type {0} in Execute.", typeof(T).Name);
- }
- else
- {
- var type = scheduledTask.ScheduledTask.GetType();
-
- Logger.Info("Queueing task {0}", type.Name);
-
- lock (_taskQueue)
- {
- if (scheduledTask.State == TaskState.Idle)
- {
- Execute(scheduledTask, new TaskExecutionOptions());
- }
- }
- }
- }
-
- /// <summary>
- /// Queues the scheduled task.
- /// </summary>
- /// <param name="task">The task.</param>
- /// <param name="options">The task options.</param>
- public void QueueScheduledTask(IScheduledTask task, TaskExecutionOptions options)
- {
- var scheduledTask = ScheduledTasks.FirstOrDefault(t => t.ScheduledTask.GetType() == task.GetType());
-
- if (scheduledTask == null)
- {
- Logger.Error("Unable to find scheduled task of type {0} in QueueScheduledTask.", task.GetType().Name);
- }
- else
- {
- QueueScheduledTask(scheduledTask, options);
- }
- }
-
- /// <summary>
- /// Queues the scheduled task.
- /// </summary>
- /// <param name="task">The task.</param>
- /// <param name="options">The task options.</param>
- private void QueueScheduledTask(IScheduledTaskWorker task, TaskExecutionOptions options)
- {
- var type = task.ScheduledTask.GetType();
-
- Logger.Info("Queueing task {0}", type.Name);
-
- lock (_taskQueue)
- {
- if (task.State == TaskState.Idle && !SuspendTriggers)
- {
- Execute(task, options);
- return;
- }
-
- _taskQueue.Enqueue(new Tuple<Type, TaskExecutionOptions>(type, options));
- }
- }
-
- /// <summary>
- /// Adds the tasks.
- /// </summary>
- /// <param name="tasks">The tasks.</param>
- public void AddTasks(IEnumerable<IScheduledTask> tasks)
- {
- var myTasks = ScheduledTasks.ToList();
-
- var list = tasks.ToList();
- myTasks.AddRange(list.Select(t => new ScheduledTaskWorker(t, ApplicationPaths, this, JsonSerializer, Logger, _fileSystem)));
-
- ScheduledTasks = myTasks.ToArray();
-
- BindToSystemEvent();
- }
-
- /// <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();
- }
- }
-
- public void Cancel(IScheduledTaskWorker task)
- {
- ((ScheduledTaskWorker)task).Cancel();
- }
-
- public Task Execute(IScheduledTaskWorker task, TaskExecutionOptions options)
- {
- return ((ScheduledTaskWorker)task).Execute(options);
- }
-
- /// <summary>
- /// Called when [task executing].
- /// </summary>
- /// <param name="task">The task.</param>
- internal void OnTaskExecuting(IScheduledTaskWorker task)
- {
- EventHelper.FireEventIfNotNull(TaskExecuting, this, new GenericEventArgs<IScheduledTaskWorker>
- {
- Argument = task
-
- }, Logger);
- }
-
- /// <summary>
- /// Called when [task completed].
- /// </summary>
- /// <param name="task">The task.</param>
- /// <param name="result">The result.</param>
- internal void OnTaskCompleted(IScheduledTaskWorker task, TaskResult result)
- {
- EventHelper.FireEventIfNotNull(TaskCompleted, task, new TaskCompletionEventArgs
- {
- Result = result,
- Task = task
-
- }, Logger);
-
- ExecuteQueuedTasks();
- }
-
- /// <summary>
- /// Executes the queued tasks.
- /// </summary>
- private void ExecuteQueuedTasks()
- {
- if (SuspendTriggers)
- {
- return;
- }
-
- Logger.Info("ExecuteQueuedTasks");
-
- // Execute queued tasks
- lock (_taskQueue)
- {
- var list = new List<Tuple<Type, TaskExecutionOptions>>();
-
- Tuple<Type, TaskExecutionOptions> item;
- while (_taskQueue.TryDequeue(out item))
- {
- if (list.All(i => i.Item1 != item.Item1))
- {
- list.Add(item);
- }
- }
-
- foreach (var enqueuedType in list)
- {
- var scheduledTask = ScheduledTasks.First(t => t.ScheduledTask.GetType() == enqueuedType.Item1);
-
- if (scheduledTask.State == TaskState.Idle)
- {
- Execute(scheduledTask, enqueuedType.Item2);
- }
- }
- }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
deleted file mode 100644
index 2cd3f4c0f5..0000000000
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
+++ /dev/null
@@ -1,217 +0,0 @@
-using MediaBrowser.Common.Configuration;
-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;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Tasks;
-
-namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
-{
- /// <summary>
- /// Deletes old cache files
- /// </summary>
- public class DeleteCacheFileTask : IScheduledTask, IConfigurableScheduledTask
- {
- /// <summary>
- /// Gets or sets the application paths.
- /// </summary>
- /// <value>The application paths.</value>
- private IApplicationPaths ApplicationPaths { get; set; }
-
- private readonly ILogger _logger;
-
- private readonly IFileSystem _fileSystem;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="DeleteCacheFileTask" /> class.
- /// </summary>
- public DeleteCacheFileTask(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem)
- {
- ApplicationPaths = appPaths;
- _logger = logger;
- _fileSystem = fileSystem;
- }
-
- /// <summary>
- /// Creates the triggers that define when the task will run
- /// </summary>
- /// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
- {
- return new[] {
-
- // Every so often
- new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
- };
- }
-
- /// <summary>
- /// Returns the task to be executed
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="progress">The progress.</param>
- /// <returns>Task.</returns>
- public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
- {
- var minDateModified = DateTime.UtcNow.AddDays(-30);
-
- try
- {
- DeleteCacheFilesFromDirectory(cancellationToken, ApplicationPaths.CachePath, minDateModified, progress);
- }
- catch (DirectoryNotFoundException)
- {
- // No biggie here. Nothing to delete
- }
-
- progress.Report(90);
-
- minDateModified = DateTime.UtcNow.AddDays(-1);
-
- try
- {
- DeleteCacheFilesFromDirectory(cancellationToken, ApplicationPaths.TempDirectory, minDateModified, progress);
- }
- catch (DirectoryNotFoundException)
- {
- // No biggie here. Nothing to delete
- }
-
- return Task.FromResult(true);
- }
-
-
- /// <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 = _fileSystem.GetFiles(directory, true)
- .Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified)
- .ToList();
-
- var index = 0;
-
- foreach (var file in filesToDelete)
- {
- double percent = index;
- percent /= filesToDelete.Count;
-
- progress.Report(100 * percent);
-
- cancellationToken.ThrowIfCancellationRequested();
-
- DeleteFile(file.FullName);
-
- index++;
- }
-
- DeleteEmptyFolders(directory);
-
- progress.Report(100);
- }
-
- private void DeleteEmptyFolders(string parent)
- {
- foreach (var directory in _fileSystem.GetDirectoryPaths(parent))
- {
- DeleteEmptyFolders(directory);
- if (!_fileSystem.GetFileSystemEntryPaths(directory).Any())
- {
- try
- {
- _fileSystem.DeleteDirectory(directory, false);
- }
- catch (UnauthorizedAccessException ex)
- {
- _logger.ErrorException("Error deleting directory {0}", ex, directory);
- }
- catch (IOException ex)
- {
- _logger.ErrorException("Error deleting directory {0}", ex, directory);
- }
- }
- }
- }
-
- private void DeleteFile(string path)
- {
- try
- {
- _fileSystem.DeleteFile(path);
- }
- catch (UnauthorizedAccessException ex)
- {
- _logger.ErrorException("Error deleting file {0}", ex, path);
- }
- catch (IOException ex)
- {
- _logger.ErrorException("Error deleting file {0}", ex, path);
- }
- }
-
- /// <summary>
- /// Gets the name of the task
- /// </summary>
- /// <value>The name.</value>
- public string Name
- {
- get { return "Cache file cleanup"; }
- }
-
- public string Key
- {
- get { return "DeleteCacheFiles"; }
- }
-
- /// <summary>
- /// Gets the description.
- /// </summary>
- /// <value>The description.</value>
- public string Description
- {
- get { return "Deletes cache files no longer needed by the system"; }
- }
-
- /// <summary>
- /// Gets the category.
- /// </summary>
- /// <value>The category.</value>
- public string Category
- {
- get
- {
- return "Maintenance";
- }
- }
-
- /// <summary>
- /// Gets a value indicating whether this instance is hidden.
- /// </summary>
- /// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value>
- public bool IsHidden
- {
- get { return true; }
- }
-
- public bool IsEnabled
- {
- get { return true; }
- }
-
- public bool IsLogged
- {
- get { return true; }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
deleted file mode 100644
index 336f91f963..0000000000
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.ScheduledTasks;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Tasks;
-
-namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
-{
- /// <summary>
- /// Deletes old log files
- /// </summary>
- public class DeleteLogFileTask : IScheduledTask, IConfigurableScheduledTask
- {
- /// <summary>
- /// Gets or sets the configuration manager.
- /// </summary>
- /// <value>The configuration manager.</value>
- private IConfigurationManager ConfigurationManager { get; set; }
-
- private readonly IFileSystem _fileSystem;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="DeleteLogFileTask" /> class.
- /// </summary>
- /// <param name="configurationManager">The configuration manager.</param>
- public DeleteLogFileTask(IConfigurationManager configurationManager, IFileSystem fileSystem)
- {
- ConfigurationManager = configurationManager;
- _fileSystem = fileSystem;
- }
-
- /// <summary>
- /// Creates the triggers that define when the task will run
- /// </summary>
- /// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
- {
- return new[] {
-
- // Every so often
- new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
- };
- }
-
- /// <summary>
- /// Returns the task to be executed
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="progress">The progress.</param>
- /// <returns>Task.</returns>
- public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
- {
- // Delete log files more than n days old
- var minDateModified = DateTime.UtcNow.AddDays(-ConfigurationManager.CommonConfiguration.LogFileRetentionDays);
-
- var filesToDelete = _fileSystem.GetFiles(ConfigurationManager.CommonApplicationPaths.LogDirectoryPath, true)
- .Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified)
- .ToList();
-
- var index = 0;
-
- foreach (var file in filesToDelete)
- {
- double percent = index;
- percent /= filesToDelete.Count;
-
- progress.Report(100 * percent);
-
- cancellationToken.ThrowIfCancellationRequested();
-
- _fileSystem.DeleteFile(file.FullName);
-
- index++;
- }
-
- progress.Report(100);
-
- return Task.FromResult(true);
- }
-
- public string Key
- {
- get { return "CleanLogFiles"; }
- }
-
- /// <summary>
- /// Gets the name of the task
- /// </summary>
- /// <value>The name.</value>
- public string Name
- {
- get { return "Log file cleanup"; }
- }
-
- /// <summary>
- /// Gets the description.
- /// </summary>
- /// <value>The description.</value>
- public string Description
- {
- get { return string.Format("Deletes log files that are more than {0} days old.", ConfigurationManager.CommonConfiguration.LogFileRetentionDays); }
- }
-
- /// <summary>
- /// Gets the category.
- /// </summary>
- /// <value>The category.</value>
- public string Category
- {
- get
- {
- return "Maintenance";
- }
- }
-
- /// <summary>
- /// Gets a value indicating whether this instance is hidden.
- /// </summary>
- /// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value>
- public bool IsHidden
- {
- get { return true; }
- }
-
- public bool IsEnabled
- {
- get { return true; }
- }
-
- public bool IsLogged
- {
- get { return true; }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerFileTask.cs
deleted file mode 100644
index 3c33df832e..0000000000
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerFileTask.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.ScheduledTasks;
-using MediaBrowser.Model.Logging;
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Model.Tasks;
-
-namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
-{
- /// <summary>
- /// Class ReloadLoggerFileTask
- /// </summary>
- public class ReloadLoggerFileTask : IScheduledTask, IConfigurableScheduledTask
- {
- /// <summary>
- /// Gets or sets the log manager.
- /// </summary>
- /// <value>The log manager.</value>
- private ILogManager LogManager { get; set; }
- /// <summary>
- /// Gets or sets the configuration manager.
- /// </summary>
- /// <value>The configuration manager.</value>
- private IConfigurationManager ConfigurationManager { get; set; }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="ReloadLoggerFileTask" /> class.
- /// </summary>
- /// <param name="logManager">The logManager.</param>
- /// <param name="configurationManager">The configuration manager.</param>
- public ReloadLoggerFileTask(ILogManager logManager, IConfigurationManager configurationManager)
- {
- LogManager = logManager;
- ConfigurationManager = configurationManager;
- }
-
- /// <summary>
- /// Gets the default triggers.
- /// </summary>
- /// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
- {
- var trigger = new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerDaily, TimeOfDayTicks = TimeSpan.FromHours(0).Ticks }; //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>
- public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
- {
- cancellationToken.ThrowIfCancellationRequested();
-
- progress.Report(0);
-
- LogManager.ReloadLogger(ConfigurationManager.CommonConfiguration.EnableDebugLevelLogging
- ? LogSeverity.Debug
- : LogSeverity.Info);
-
- return Task.FromResult(true);
- }
-
- /// <summary>
- /// Gets the name.
- /// </summary>
- /// <value>The name.</value>
- public string Name
- {
- get { return "Start new log file"; }
- }
-
- public string Key { get; }
-
- /// <summary>
- /// Gets the description.
- /// </summary>
- /// <value>The description.</value>
- public string Description
- {
- get { return "Moves logging to a new file to help reduce log file sizes."; }
- }
-
- /// <summary>
- /// Gets the category.
- /// </summary>
- /// <value>The category.</value>
- public string Category
- {
- get { return "Application"; }
- }
-
- public bool IsHidden
- {
- get { return true; }
- }
-
- public bool IsEnabled
- {
- get { return true; }
- }
-
- public bool IsLogged
- {
- get { return true; }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs
deleted file mode 100644
index 318802e07d..0000000000
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-using System;
-using System.Threading;
-using MediaBrowser.Model.Events;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Tasks;
-
-namespace MediaBrowser.Common.ScheduledTasks
-{
- /// <summary>
- /// Represents a task trigger that fires on a weekly basis
- /// </summary>
- public class WeeklyTrigger : ITaskTrigger
- {
- /// <summary>
- /// Get the time of day to trigger the task to run
- /// </summary>
- /// <value>The time of day.</value>
- public TimeSpan TimeOfDay { get; set; }
-
- /// <summary>
- /// Gets or sets the day of week.
- /// </summary>
- /// <value>The day of week.</value>
- public DayOfWeek DayOfWeek { get; set; }
-
- /// <summary>
- /// Gets the execution properties of this task.
- /// </summary>
- /// <value>
- /// The execution properties of this task.
- /// </value>
- public TaskExecutionOptions TaskOptions { get; set; }
-
- /// <summary>
- /// Gets or sets the timer.
- /// </summary>
- /// <value>The timer.</value>
- private Timer Timer { get; set; }
-
- /// <summary>
- /// Stars waiting for the trigger action
- /// </summary>
- /// <param name="lastResult">The last result.</param>
- /// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
- public void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup)
- {
- DisposeTimer();
-
- var triggerDate = GetNextTriggerDateTime();
-
- Timer = new Timer(state => OnTriggered(), null, triggerDate - DateTime.Now, TimeSpan.FromMilliseconds(-1));
- }
-
- /// <summary>
- /// Gets the next trigger date time.
- /// </summary>
- /// <returns>DateTime.</returns>
- private DateTime GetNextTriggerDateTime()
- {
- var now = DateTime.Now;
-
- // If it's on the same day
- if (now.DayOfWeek == DayOfWeek)
- {
- // It's either later today, or a week from now
- return now.TimeOfDay < TimeOfDay ? now.Date.Add(TimeOfDay) : now.Date.AddDays(7).Add(TimeOfDay);
- }
-
- var triggerDate = now.Date;
-
- // Walk the date forward until we get to the trigger day
- while (triggerDate.DayOfWeek != DayOfWeek)
- {
- triggerDate = triggerDate.AddDays(1);
- }
-
- // Return the trigger date plus the time offset
- return triggerDate.Add(TimeOfDay);
- }
-
- /// <summary>
- /// Stops waiting for the trigger action
- /// </summary>
- public void Stop()
- {
- DisposeTimer();
- }
-
- /// <summary>
- /// Disposes the timer.
- /// </summary>
- private void DisposeTimer()
- {
- if (Timer != null)
- {
- Timer.Dispose();
- }
- }
-
- /// <summary>
- /// Occurs when [triggered].
- /// </summary>
- public event EventHandler<GenericEventArgs<TaskExecutionOptions>> Triggered;
-
- /// <summary>
- /// Called when [triggered].
- /// </summary>
- private void OnTriggered()
- {
- if (Triggered != null)
- {
- Triggered(this, new GenericEventArgs<TaskExecutionOptions>(TaskOptions));
- }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs b/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs
deleted file mode 100644
index 78515cd141..0000000000
--- a/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs
+++ /dev/null
@@ -1,157 +0,0 @@
-using MediaBrowser.Common.Configuration;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Security.Cryptography;
-using System.Text;
-
-namespace MediaBrowser.Common.Implementations.Security
-{
- internal class MBLicenseFile
- {
- private readonly IApplicationPaths _appPaths;
-
- public string RegKey
- {
- get { return _regKey; }
- set
- {
- if (value != _regKey)
- {
- //if key is changed - clear out our saved validations
- _updateRecords.Clear();
- _regKey = value;
- }
- }
- }
-
- private string Filename
- {
- get
- {
- return Path.Combine(_appPaths.ConfigurationDirectoryPath, "mb.lic");
- }
- }
-
- private readonly ConcurrentDictionary<Guid, DateTime> _updateRecords = new ConcurrentDictionary<Guid, DateTime>();
- private readonly object _fileLock = new object();
- private string _regKey;
-
- public MBLicenseFile(IApplicationPaths appPaths)
- {
- _appPaths = appPaths;
-
- Load();
- }
-
- private void SetUpdateRecord(Guid key, DateTime value)
- {
- _updateRecords.AddOrUpdate(key, value, (k, v) => value);
- }
-
- public void AddRegCheck(string featureId)
- {
- using (var provider = new MD5CryptoServiceProvider())
- {
- var key = new Guid(provider.ComputeHash(Encoding.Unicode.GetBytes(featureId)));
- var value = DateTime.UtcNow;
-
- SetUpdateRecord(key, value);
- Save();
- }
-
- }
-
- public void RemoveRegCheck(string featureId)
- {
- using (var provider = new MD5CryptoServiceProvider())
- {
- var key = new Guid(provider.ComputeHash(Encoding.Unicode.GetBytes(featureId)));
- DateTime val;
-
- _updateRecords.TryRemove(key, out val);
-
- Save();
- }
-
- }
-
- public DateTime LastChecked(string featureId)
- {
- using (var provider = new MD5CryptoServiceProvider())
- {
- DateTime last;
- _updateRecords.TryGetValue(new Guid(provider.ComputeHash(Encoding.Unicode.GetBytes(featureId))), out last);
-
- // guard agains people just putting a large number in the file
- return last < DateTime.UtcNow ? last : DateTime.MinValue;
- }
- }
-
- private void Load()
- {
- string[] contents = null;
- var licenseFile = Filename;
- lock (_fileLock)
- {
- try
- {
- contents = File.ReadAllLines(licenseFile);
- }
- catch (DirectoryNotFoundException)
- {
- File.Create(licenseFile).Close();
- }
- catch (FileNotFoundException)
- {
- File.Create(licenseFile).Close();
- }
- }
- if (contents != null && contents.Length > 0)
- {
- //first line is reg key
- RegKey = contents[0];
-
- //next is legacy key
- if (contents.Length > 1)
- {
- // Don't need this anymore
- }
-
- //the rest of the lines should be pairs of features and timestamps
- for (var i = 2; i < contents.Length; i = i + 2)
- {
- var feat = Guid.Parse(contents[i]);
-
- SetUpdateRecord(feat, new DateTime(Convert.ToInt64(contents[i + 1])));
- }
- }
- }
-
- public void Save()
- {
- //build our array
- var lines = new List<string>
- {
- RegKey,
-
- // Legacy key
- string.Empty
- };
-
- foreach (var pair in _updateRecords
- .ToList())
- {
- lines.Add(pair.Key.ToString());
- lines.Add(pair.Value.Ticks.ToString(CultureInfo.InvariantCulture));
- }
-
- var licenseFile = Filename;
- Directory.CreateDirectory(Path.GetDirectoryName(licenseFile));
- lock (_fileLock) File.WriteAllLines(licenseFile, lines);
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Security/MbAdmin.cs b/MediaBrowser.Common.Implementations/Security/MbAdmin.cs
deleted file mode 100644
index 76ff92c2eb..0000000000
--- a/MediaBrowser.Common.Implementations/Security/MbAdmin.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-
-namespace MediaBrowser.Common.Implementations.Security
-{
- public class MbAdmin
- {
- public const string HttpUrl = "https://www.mb3admin.com/admin/";
-
- /// <summary>
- /// Leaving as http for now until we get it squared away
- /// </summary>
- public const string HttpsUrl = "https://www.mb3admin.com/admin/";
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
deleted file mode 100644
index 5d440609ef..0000000000
--- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
+++ /dev/null
@@ -1,337 +0,0 @@
-using System.IO;
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Security;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Serialization;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Model.Net;
-
-namespace MediaBrowser.Common.Implementations.Security
-{
- /// <summary>
- /// Class PluginSecurityManager
- /// </summary>
- public class PluginSecurityManager : ISecurityManager
- {
- private const string MBValidateUrl = MbAdmin.HttpsUrl + "service/registration/validate";
- private const string AppstoreRegUrl = /*MbAdmin.HttpsUrl*/ "https://mb3admin.com/admin/service/appstore/register";
-
- /// <summary>
- /// The _is MB supporter
- /// </summary>
- private bool? _isMbSupporter;
- /// <summary>
- /// The _is MB supporter initialized
- /// </summary>
- private bool _isMbSupporterInitialized;
- /// <summary>
- /// The _is MB supporter sync lock
- /// </summary>
- private object _isMbSupporterSyncLock = new object();
-
- /// <summary>
- /// Gets a value indicating whether this instance is MB supporter.
- /// </summary>
- /// <value><c>true</c> if this instance is MB supporter; otherwise, <c>false</c>.</value>
- public bool IsMBSupporter
- {
- get
- {
- LazyInitializer.EnsureInitialized(ref _isMbSupporter, ref _isMbSupporterInitialized, ref _isMbSupporterSyncLock, () => GetSupporterRegistrationStatus().Result.IsRegistered);
- return _isMbSupporter.Value;
- }
- }
-
- private MBLicenseFile _licenseFile;
- private MBLicenseFile LicenseFile
- {
- get { return _licenseFile ?? (_licenseFile = new MBLicenseFile(_appPaths)); }
- }
-
- private readonly IHttpClient _httpClient;
- private readonly IJsonSerializer _jsonSerializer;
- private readonly IApplicationHost _appHost;
- private readonly ILogger _logger;
- private readonly IApplicationPaths _appPaths;
-
- private IEnumerable<IRequiresRegistration> _registeredEntities;
- protected IEnumerable<IRequiresRegistration> RegisteredEntities
- {
- get
- {
- return _registeredEntities ?? (_registeredEntities = _appHost.GetExports<IRequiresRegistration>());
- }
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="PluginSecurityManager" /> class.
- /// </summary>
- public PluginSecurityManager(IApplicationHost appHost, IHttpClient httpClient, IJsonSerializer jsonSerializer,
- IApplicationPaths appPaths, ILogManager logManager)
- {
- if (httpClient == null)
- {
- throw new ArgumentNullException("httpClient");
- }
-
- _appHost = appHost;
- _httpClient = httpClient;
- _jsonSerializer = jsonSerializer;
- _appPaths = appPaths;
- _logger = logManager.GetLogger("SecurityManager");
- }
-
- /// <summary>
- /// Load all registration info for all entities that require registration
- /// </summary>
- /// <returns></returns>
- public async Task LoadAllRegistrationInfo()
- {
- var tasks = new List<Task>();
-
- ResetSupporterInfo();
- tasks.AddRange(RegisteredEntities.Select(i => i.LoadRegistrationInfoAsync()));
- await Task.WhenAll(tasks);
- }
-
- /// <summary>
- /// Gets the registration status.
- /// This overload supports existing plug-ins.
- /// </summary>
- /// <param name="feature">The feature.</param>
- /// <param name="mb2Equivalent">The MB2 equivalent.</param>
- /// <returns>Task{MBRegistrationRecord}.</returns>
- public Task<MBRegistrationRecord> GetRegistrationStatus(string feature, string mb2Equivalent = null)
- {
- return GetRegistrationStatusInternal(feature, mb2Equivalent);
- }
-
- /// <summary>
- /// Gets the registration status.
- /// </summary>
- /// <param name="feature">The feature.</param>
- /// <param name="mb2Equivalent">The MB2 equivalent.</param>
- /// <param name="version">The version of this feature</param>
- /// <returns>Task{MBRegistrationRecord}.</returns>
- public Task<MBRegistrationRecord> GetRegistrationStatus(string feature, string mb2Equivalent, string version)
- {
- return GetRegistrationStatusInternal(feature, mb2Equivalent, version);
- }
-
- private Task<MBRegistrationRecord> GetSupporterRegistrationStatus()
- {
- return GetRegistrationStatusInternal("MBSupporter", null, _appHost.ApplicationVersion.ToString());
- }
-
- /// <summary>
- /// Gets or sets the supporter key.
- /// </summary>
- /// <value>The supporter key.</value>
- public string SupporterKey
- {
- get
- {
- return LicenseFile.RegKey;
- }
- set
- {
- var newValue = value;
- if (newValue != null)
- {
- newValue = newValue.Trim();
- }
-
- if (newValue != LicenseFile.RegKey)
- {
- LicenseFile.RegKey = newValue;
- LicenseFile.Save();
-
- // re-load registration info
- Task.Run(() => LoadAllRegistrationInfo());
- }
- }
- }
-
- /// <summary>
- /// Register an app store sale with our back-end. It will validate the transaction with the store
- /// and then register the proper feature and then fill in the supporter key on success.
- /// </summary>
- /// <param name="parameters">Json parameters to send to admin server</param>
- public async Task RegisterAppStoreSale(string parameters)
- {
- var options = new HttpRequestOptions()
- {
- Url = AppstoreRegUrl,
- CancellationToken = CancellationToken.None,
- BufferContent = false
- };
- options.RequestHeaders.Add("X-Emby-Token", _appHost.SystemId);
- options.RequestContent = parameters;
- options.RequestContentType = "application/json";
-
- try
- {
- using (var response = await _httpClient.Post(options).ConfigureAwait(false))
- {
- var reg = _jsonSerializer.DeserializeFromStream<RegRecord>(response.Content);
-
- if (reg == null)
- {
- var msg = "Result from appstore registration was null.";
- _logger.Error(msg);
- throw new ApplicationException(msg);
- }
- if (!String.IsNullOrEmpty(reg.key))
- {
- SupporterKey = reg.key;
- }
- }
-
- }
- catch (ApplicationException)
- {
- SaveAppStoreInfo(parameters);
- throw;
- }
- catch (HttpException e)
- {
- _logger.ErrorException("Error registering appstore purchase {0}", e, parameters ?? "NO PARMS SENT");
-
- if (e.StatusCode.HasValue && e.StatusCode.Value == HttpStatusCode.PaymentRequired)
- {
- throw new PaymentRequiredException();
- }
- throw new ApplicationException("Error registering store sale");
- }
- catch (Exception e)
- {
- _logger.ErrorException("Error registering appstore purchase {0}", e, parameters ?? "NO PARMS SENT");
- SaveAppStoreInfo(parameters);
- //TODO - could create a re-try routine on start-up if this file is there. For now we can handle manually.
- throw new ApplicationException("Error registering store sale");
- }
-
- }
-
- private void SaveAppStoreInfo(string info)
- {
- // Save all transaction information to a file
-
- try
- {
- File.WriteAllText(Path.Combine(_appPaths.ProgramDataPath, "apptrans-error.txt"), info);
- }
- catch (IOException)
- {
-
- }
- }
-
- private async Task<MBRegistrationRecord> GetRegistrationStatusInternal(string feature,
- string mb2Equivalent = null,
- string version = null)
- {
- var lastChecked = LicenseFile.LastChecked(feature);
-
- //check the reg file first to alleviate strain on the MB admin server - must actually check in every 30 days tho
- var reg = new RegRecord
- {
- // Cache the result for up to a week
- registered = lastChecked > DateTime.UtcNow.AddDays(-7)
- };
-
- var success = reg.registered;
-
- if (!(lastChecked > DateTime.UtcNow.AddDays(-1)))
- {
- var data = new Dictionary<string, string>
- {
- { "feature", feature },
- { "key", SupporterKey },
- { "mac", _appHost.SystemId },
- { "systemid", _appHost.SystemId },
- { "mb2equiv", mb2Equivalent },
- { "ver", version },
- { "platform", _appHost.OperatingSystemDisplayName },
- { "isservice", _appHost.IsRunningAsService.ToString().ToLower() }
- };
-
- try
- {
- var options = new HttpRequestOptions
- {
- Url = MBValidateUrl,
-
- // Seeing block length errors
- EnableHttpCompression = false,
- BufferContent = false
- };
-
- options.SetPostData(data);
-
- using (var json = (await _httpClient.Post(options).ConfigureAwait(false)).Content)
- {
- reg = _jsonSerializer.DeserializeFromStream<RegRecord>(json);
- success = true;
- }
-
- if (reg.registered)
- {
- LicenseFile.AddRegCheck(feature);
- }
- else
- {
- LicenseFile.RemoveRegCheck(feature);
- }
-
- }
- catch (Exception e)
- {
- _logger.ErrorException("Error checking registration status of {0}", e, feature);
- }
- }
-
- var record = new MBRegistrationRecord
- {
- IsRegistered = reg.registered,
- ExpirationDate = reg.expDate,
- RegChecked = true,
- RegError = !success
- };
-
- record.TrialVersion = IsInTrial(reg.expDate, record.RegChecked, record.IsRegistered);
- record.IsValid = !record.RegChecked || record.IsRegistered || record.TrialVersion;
-
- return record;
- }
-
- private bool IsInTrial(DateTime expirationDate, bool regChecked, bool isRegistered)
- {
- //don't set this until we've successfully obtained exp date
- if (!regChecked)
- {
- return false;
- }
-
- var isInTrial = expirationDate > DateTime.UtcNow;
-
- return isInTrial && !isRegistered;
- }
-
- /// <summary>
- /// Resets the supporter info.
- /// </summary>
- private void ResetSupporterInfo()
- {
- _isMbSupporter = null;
- _isMbSupporterInitialized = false;
- }
- }
-} \ No newline at end of file
diff --git a/MediaBrowser.Common.Implementations/Security/RegRecord.cs b/MediaBrowser.Common.Implementations/Security/RegRecord.cs
deleted file mode 100644
index ece70b7726..0000000000
--- a/MediaBrowser.Common.Implementations/Security/RegRecord.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-
-namespace MediaBrowser.Common.Implementations.Security
-{
- class RegRecord
- {
- public string featId { get; set; }
- public bool registered { get; set; }
- public DateTime expDate { get; set; }
- public string key { get; set; }
- }
-} \ No newline at end of file
diff --git a/MediaBrowser.Common.Implementations/Security/SuppporterInfoResponse.cs b/MediaBrowser.Common.Implementations/Security/SuppporterInfoResponse.cs
deleted file mode 100644
index 49c5af8d82..0000000000
--- a/MediaBrowser.Common.Implementations/Security/SuppporterInfoResponse.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-
-namespace MediaBrowser.Common.Implementations.Security
-{
- internal class SuppporterInfoResponse
- {
- public string email { get; set; }
- public string supporterKey { get; set; }
- public int totalRegs { get; set; }
- public int totalMachines { get; set; }
- public string expDate { get; set; }
- public string regDate { get; set; }
- public string planType { get; set; }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs
deleted file mode 100644
index 98d2967ac5..0000000000
--- a/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs
+++ /dev/null
@@ -1,228 +0,0 @@
-using MediaBrowser.Model.Serialization;
-using System;
-using System.IO;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Logging;
-
-namespace MediaBrowser.Common.Implementations.Serialization
-{
- /// <summary>
- /// Provides a wrapper around third party json serialization.
- /// </summary>
- public class JsonSerializer : IJsonSerializer
- {
- private readonly IFileSystem _fileSystem;
- private readonly ILogger _logger;
-
- public JsonSerializer(IFileSystem fileSystem, ILogger logger)
- {
- _fileSystem = fileSystem;
- _logger = logger;
- Configure();
- }
-
- /// <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");
- }
-
- ServiceStack.Text.JsonSerializer.SerializeToStream(obj, obj.GetType(), stream);
- }
-
- /// <summary>
- /// Serializes to file.
- /// </summary>
- /// <param name="obj">The obj.</param>
- /// <param name="file">The file.</param>
- /// <exception cref="System.ArgumentNullException">obj</exception>
- public void SerializeToFile(object obj, string file)
- {
- if (obj == null)
- {
- throw new ArgumentNullException("obj");
- }
-
- if (string.IsNullOrEmpty(file))
- {
- throw new ArgumentNullException("file");
- }
-
- using (Stream stream = _fileSystem.GetFileStream(file, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
- {
- SerializeToStream(obj, stream);
- }
- }
-
- private Stream OpenFile(string path)
- {
- _logger.Debug("Deserializing file {0}", path);
- return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 131072);
- }
-
- /// <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 = OpenFile(file))
- {
- return DeserializeFromStream(stream, type);
- }
- }
-
- /// <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 = OpenFile(file))
- {
- return 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.DateHandler.ISO8601;
- ServiceStack.Text.JsConfig.ExcludeTypeInfo = true;
- ServiceStack.Text.JsConfig.IncludeNullValues = false;
- ServiceStack.Text.JsConfig.AlwaysUseUtc = true;
- ServiceStack.Text.JsConfig.AssumeUtc = true;
- }
-
- /// <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>
- /// <param name="obj">The obj.</param>
- /// <returns>System.String.</returns>
- /// <exception cref="System.ArgumentNullException">obj</exception>
- public string SerializeToString(object obj)
- {
- if (obj == null)
- {
- throw new ArgumentNullException("obj");
- }
-
- return ServiceStack.Text.JsonSerializer.SerializeToString(obj, obj.GetType());
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs
deleted file mode 100644
index f486813049..0000000000
--- a/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs
+++ /dev/null
@@ -1,130 +0,0 @@
-using MediaBrowser.Model.Serialization;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.IO;
-using System.Xml;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Logging;
-
-namespace MediaBrowser.Common.Implementations.Serialization
-{
- /// <summary>
- /// Provides a wrapper around third party xml serialization.
- /// </summary>
- public class XmlSerializer : IXmlSerializer
- {
- private readonly IFileSystem _fileSystem;
- private readonly ILogger _logger;
-
- public XmlSerializer(IFileSystem fileSystem, ILogger logger)
- {
- _fileSystem = fileSystem;
- _logger = logger;
- }
-
- // Need to cache these
- // http://dotnetcodebox.blogspot.com/2013/01/xmlserializer-class-may-result-in.html
- private readonly Dictionary<string, System.Xml.Serialization.XmlSerializer> _serializers =
- new Dictionary<string, System.Xml.Serialization.XmlSerializer>();
-
- private System.Xml.Serialization.XmlSerializer GetSerializer(Type type)
- {
- var key = type.FullName;
- lock (_serializers)
- {
- System.Xml.Serialization.XmlSerializer serializer;
- if (!_serializers.TryGetValue(key, out serializer))
- {
- serializer = new System.Xml.Serialization.XmlSerializer(type);
- _serializers[key] = serializer;
- }
- return serializer;
- }
- }
-
- /// <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 = GetSerializer(obj.GetType());
- netSerializer.Serialize(writer, obj);
- }
-
- /// <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 = GetSerializer(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>
- /// Serializes to file.
- /// </summary>
- /// <param name="obj">The obj.</param>
- /// <param name="file">The file.</param>
- public void SerializeToFile(object obj, string file)
- {
- _logger.Debug("Serializing to file {0}", 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)
- {
- _logger.Debug("Deserializing file {0}", file);
- using (var stream = _fileSystem.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);
- }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs
deleted file mode 100644
index 371c2ea113..0000000000
--- a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs
+++ /dev/null
@@ -1,269 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Updates;
-
-namespace MediaBrowser.Common.Implementations.Updates
-{
- public class GithubUpdater
- {
- private readonly IHttpClient _httpClient;
- private readonly IJsonSerializer _jsonSerializer;
-
- public GithubUpdater(IHttpClient httpClient, IJsonSerializer jsonSerializer)
- {
- _httpClient = httpClient;
- _jsonSerializer = jsonSerializer;
- }
-
- public async Task<CheckForUpdateResult> CheckForUpdateResult(string organzation, string repository, Version minVersion, PackageVersionClass updateLevel, string assetFilename, string packageName, string targetFilename, TimeSpan cacheLength, CancellationToken cancellationToken)
- {
- var url = string.Format("https://api.github.com/repos/{0}/{1}/releases", organzation, repository);
-
- var options = new HttpRequestOptions
- {
- Url = url,
- EnableKeepAlive = false,
- CancellationToken = cancellationToken,
- UserAgent = "Emby/3.0",
- BufferContent = false
- };
-
- if (cacheLength.Ticks > 0)
- {
- options.CacheMode = CacheMode.Unconditional;
- options.CacheLength = cacheLength;
- }
-
- using (var stream = await _httpClient.Get(options).ConfigureAwait(false))
- {
- var obj = _jsonSerializer.DeserializeFromStream<RootObject[]>(stream);
-
- return CheckForUpdateResult(obj, minVersion, updateLevel, assetFilename, packageName, targetFilename);
- }
- }
-
- private CheckForUpdateResult CheckForUpdateResult(RootObject[] obj, Version minVersion, PackageVersionClass updateLevel, string assetFilename, string packageName, string targetFilename)
- {
- if (updateLevel == PackageVersionClass.Release)
- {
- // Technically all we need to do is check that it's not pre-release
- // But let's addititional checks for -beta and -dev to handle builds that might be temporarily tagged incorrectly.
- obj = obj.Where(i => !i.prerelease && !i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) && !i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase)).ToArray();
- }
- else if (updateLevel == PackageVersionClass.Beta)
- {
- obj = obj.Where(i => !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase)).ToArray();
- }
- else if (updateLevel == PackageVersionClass.Dev)
- {
- obj = obj.Where(i => !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) || i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase)).ToArray();
- }
-
- var availableUpdate = obj
- .Select(i => CheckForUpdateResult(i, minVersion, assetFilename, packageName, targetFilename))
- .Where(i => i != null)
- .OrderByDescending(i => Version.Parse(i.AvailableVersion))
- .FirstOrDefault();
-
- return availableUpdate ?? new CheckForUpdateResult
- {
- IsUpdateAvailable = false
- };
- }
-
- private bool MatchesUpdateLevel(RootObject i, PackageVersionClass updateLevel)
- {
- if (updateLevel == PackageVersionClass.Beta)
- {
- return !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase);
- }
- if (updateLevel == PackageVersionClass.Dev)
- {
- return !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) ||
- i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase);
- }
-
- // Technically all we need to do is check that it's not pre-release
- // But let's addititional checks for -beta and -dev to handle builds that might be temporarily tagged incorrectly.
- return !i.prerelease && !i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) &&
- !i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase);
- }
-
- public async Task<List<RootObject>> GetLatestReleases(string organzation, string repository, string assetFilename, CancellationToken cancellationToken)
- {
- var list = new List<RootObject>();
-
- var url = string.Format("https://api.github.com/repos/{0}/{1}/releases", organzation, repository);
-
- var options = new HttpRequestOptions
- {
- Url = url,
- EnableKeepAlive = false,
- CancellationToken = cancellationToken,
- UserAgent = "Emby/3.0",
- BufferContent = false
- };
-
- using (var stream = await _httpClient.Get(options).ConfigureAwait(false))
- {
- var obj = _jsonSerializer.DeserializeFromStream<RootObject[]>(stream);
-
- obj = obj.Where(i => (i.assets ?? new List<Asset>()).Any(a => IsAsset(a, assetFilename))).ToArray();
-
- list.AddRange(obj.Where(i => MatchesUpdateLevel(i, PackageVersionClass.Release)).OrderByDescending(GetVersion).Take(1));
- list.AddRange(obj.Where(i => MatchesUpdateLevel(i, PackageVersionClass.Beta)).OrderByDescending(GetVersion).Take(1));
- list.AddRange(obj.Where(i => MatchesUpdateLevel(i, PackageVersionClass.Dev)).OrderByDescending(GetVersion).Take(1));
-
- return list;
- }
- }
-
- public Version GetVersion(RootObject obj)
- {
- Version version;
- if (!Version.TryParse(obj.tag_name, out version))
- {
- return new Version(1, 0);
- }
-
- return version;
- }
-
- private CheckForUpdateResult CheckForUpdateResult(RootObject obj, Version minVersion, string assetFilename, string packageName, string targetFilename)
- {
- Version version;
- if (!Version.TryParse(obj.tag_name, out version))
- {
- return null;
- }
-
- if (version < minVersion)
- {
- return null;
- }
-
- var asset = (obj.assets ?? new List<Asset>()).FirstOrDefault(i => IsAsset(i, assetFilename));
-
- if (asset == null)
- {
- return null;
- }
-
- return new CheckForUpdateResult
- {
- AvailableVersion = version.ToString(),
- IsUpdateAvailable = version > minVersion,
- Package = new PackageVersionInfo
- {
- classification = obj.prerelease ?
- (obj.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase) ? PackageVersionClass.Dev : PackageVersionClass.Beta) :
- PackageVersionClass.Release,
- name = packageName,
- sourceUrl = asset.browser_download_url,
- targetFilename = targetFilename,
- versionStr = version.ToString(),
- requiredVersionStr = "1.0.0",
- description = obj.body,
- infoUrl = obj.html_url
- }
- };
- }
-
- private bool IsAsset(Asset asset, string assetFilename)
- {
- var downloadFilename = Path.GetFileName(asset.browser_download_url) ?? string.Empty;
-
- if (downloadFilename.IndexOf(assetFilename, StringComparison.OrdinalIgnoreCase) != -1)
- {
- return true;
- }
-
- return string.Equals(assetFilename, downloadFilename, StringComparison.OrdinalIgnoreCase);
- }
-
- public class Uploader
- {
- public string login { get; set; }
- public int id { get; set; }
- public string avatar_url { get; set; }
- public string gravatar_id { get; set; }
- public string url { get; set; }
- public string html_url { get; set; }
- public string followers_url { get; set; }
- public string following_url { get; set; }
- public string gists_url { get; set; }
- public string starred_url { get; set; }
- public string subscriptions_url { get; set; }
- public string organizations_url { get; set; }
- public string repos_url { get; set; }
- public string events_url { get; set; }
- public string received_events_url { get; set; }
- public string type { get; set; }
- public bool site_admin { get; set; }
- }
-
- public class Asset
- {
- public string url { get; set; }
- public int id { get; set; }
- public string name { get; set; }
- public object label { get; set; }
- public Uploader uploader { get; set; }
- public string content_type { get; set; }
- public string state { get; set; }
- public int size { get; set; }
- public int download_count { get; set; }
- public string created_at { get; set; }
- public string updated_at { get; set; }
- public string browser_download_url { get; set; }
- }
-
- public class Author
- {
- public string login { get; set; }
- public int id { get; set; }
- public string avatar_url { get; set; }
- public string gravatar_id { get; set; }
- public string url { get; set; }
- public string html_url { get; set; }
- public string followers_url { get; set; }
- public string following_url { get; set; }
- public string gists_url { get; set; }
- public string starred_url { get; set; }
- public string subscriptions_url { get; set; }
- public string organizations_url { get; set; }
- public string repos_url { get; set; }
- public string events_url { get; set; }
- public string received_events_url { get; set; }
- public string type { get; set; }
- public bool site_admin { get; set; }
- }
-
- public class RootObject
- {
- public string url { get; set; }
- public string assets_url { get; set; }
- public string upload_url { get; set; }
- public string html_url { get; set; }
- public int id { get; set; }
- public string tag_name { get; set; }
- public string target_commitish { get; set; }
- public string name { get; set; }
- public bool draft { get; set; }
- public Author author { get; set; }
- public bool prerelease { get; set; }
- public string created_at { get; set; }
- public string published_at { get; set; }
- public List<Asset> assets { get; set; }
- public string tarball_url { get; set; }
- public string zipball_url { get; set; }
- public string body { get; set; }
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
deleted file mode 100644
index 934898f778..0000000000
--- a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
+++ /dev/null
@@ -1,686 +0,0 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Events;
-using MediaBrowser.Common.Implementations.Security;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Plugins;
-using MediaBrowser.Common.Progress;
-using MediaBrowser.Common.Security;
-using MediaBrowser.Common.Updates;
-using MediaBrowser.Model.Events;
-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;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.IO;
-
-namespace MediaBrowser.Common.Implementations.Updates
-{
- /// <summary>
- /// Manages all install, uninstall and update operations (both plugins and system)
- /// </summary>
- public class InstallationManager : IInstallationManager
- {
- public event EventHandler<InstallationEventArgs> PackageInstalling;
- public event EventHandler<InstallationEventArgs> PackageInstallationCompleted;
- public event EventHandler<InstallationFailedEventArgs> PackageInstallationFailed;
- public event EventHandler<InstallationEventArgs> PackageInstallationCancelled;
-
- /// <summary>
- /// The current installations
- /// </summary>
- public List<Tuple<InstallationInfo, CancellationTokenSource>> CurrentInstallations { get; set; }
-
- /// <summary>
- /// The completed installations
- /// </summary>
- public ConcurrentBag<InstallationInfo> CompletedInstallations { get; set; }
-
- #region PluginUninstalled Event
- /// <summary>
- /// Occurs when [plugin uninstalled].
- /// </summary>
- public event EventHandler<GenericEventArgs<IPlugin>> PluginUninstalled;
-
- /// <summary>
- /// Called when [plugin uninstalled].
- /// </summary>
- /// <param name="plugin">The plugin.</param>
- private void OnPluginUninstalled(IPlugin plugin)
- {
- EventHelper.FireEventIfNotNull(PluginUninstalled, this, new GenericEventArgs<IPlugin> { Argument = plugin }, _logger);
- }
- #endregion
-
- #region PluginUpdated Event
- /// <summary>
- /// Occurs when [plugin updated].
- /// </summary>
- public event EventHandler<GenericEventArgs<Tuple<IPlugin, PackageVersionInfo>>> PluginUpdated;
- /// <summary>
- /// Called when [plugin updated].
- /// </summary>
- /// <param name="plugin">The plugin.</param>
- /// <param name="newVersion">The new version.</param>
- private void OnPluginUpdated(IPlugin plugin, PackageVersionInfo newVersion)
- {
- _logger.Info("Plugin updated: {0} {1} {2}", newVersion.name, newVersion.versionStr ?? string.Empty, newVersion.classification);
-
- EventHelper.FireEventIfNotNull(PluginUpdated, this, new GenericEventArgs<Tuple<IPlugin, PackageVersionInfo>> { Argument = new Tuple<IPlugin, PackageVersionInfo>(plugin, newVersion) }, _logger);
-
- _applicationHost.NotifyPendingRestart();
- }
- #endregion
-
- #region PluginInstalled Event
- /// <summary>
- /// Occurs when [plugin updated].
- /// </summary>
- public event EventHandler<GenericEventArgs<PackageVersionInfo>> PluginInstalled;
- /// <summary>
- /// Called when [plugin installed].
- /// </summary>
- /// <param name="package">The package.</param>
- private void OnPluginInstalled(PackageVersionInfo package)
- {
- _logger.Info("New plugin installed: {0} {1} {2}", package.name, package.versionStr ?? string.Empty, package.classification);
-
- EventHelper.FireEventIfNotNull(PluginInstalled, this, new GenericEventArgs<PackageVersionInfo> { Argument = package }, _logger);
-
- _applicationHost.NotifyPendingRestart();
- }
- #endregion
-
- /// <summary>
- /// The _logger
- /// </summary>
- private readonly ILogger _logger;
-
- private readonly IApplicationPaths _appPaths;
- private readonly IHttpClient _httpClient;
- private readonly IJsonSerializer _jsonSerializer;
- private readonly ISecurityManager _securityManager;
- private readonly IConfigurationManager _config;
- private readonly IFileSystem _fileSystem;
-
- /// <summary>
- /// Gets the application host.
- /// </summary>
- /// <value>The application host.</value>
- private readonly IApplicationHost _applicationHost;
-
- public InstallationManager(ILogger logger, IApplicationHost appHost, IApplicationPaths appPaths, IHttpClient httpClient, IJsonSerializer jsonSerializer, ISecurityManager securityManager, IConfigurationManager config, IFileSystem fileSystem)
- {
- if (logger == null)
- {
- throw new ArgumentNullException("logger");
- }
-
- CurrentInstallations = new List<Tuple<InstallationInfo, CancellationTokenSource>>();
- CompletedInstallations = new ConcurrentBag<InstallationInfo>();
-
- _applicationHost = appHost;
- _appPaths = appPaths;
- _httpClient = httpClient;
- _jsonSerializer = jsonSerializer;
- _securityManager = securityManager;
- _config = config;
- _fileSystem = fileSystem;
- _logger = logger;
- }
-
- private Version GetPackageVersion(PackageVersionInfo version)
- {
- return new Version(ValueOrDefault(version.versionStr, "0.0.0.1"));
- }
-
- private static string ValueOrDefault(string str, string def)
- {
- return string.IsNullOrEmpty(str) ? def : str;
- }
-
- /// <summary>
- /// Gets all available packages.
- /// </summary>
- /// <returns>Task{List{PackageInfo}}.</returns>
- public async Task<IEnumerable<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken,
- bool withRegistration = true,
- string packageType = null,
- Version applicationVersion = null)
- {
- var data = new Dictionary<string, string>
- {
- { "key", _securityManager.SupporterKey },
- { "mac", _applicationHost.SystemId },
- { "systemid", _applicationHost.SystemId }
- };
-
- if (withRegistration)
- {
- using (var json = await _httpClient.Post(MbAdmin.HttpsUrl + "service/package/retrieveall", data, cancellationToken).ConfigureAwait(false))
- {
- cancellationToken.ThrowIfCancellationRequested();
-
- var packages = _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(json).ToList();
-
- return FilterPackages(packages, packageType, applicationVersion);
- }
- }
- else
- {
- var packages = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false);
-
- return FilterPackages(packages.ToList(), packageType, applicationVersion);
- }
- }
-
- private DateTime _lastPackageUpdateTime;
-
- /// <summary>
- /// Gets all available packages.
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task{List{PackageInfo}}.</returns>
- public async Task<IEnumerable<PackageInfo>> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken)
- {
- _logger.Info("Opening {0}", PackageCachePath);
- try
- {
- using (var stream = _fileSystem.OpenRead(PackageCachePath))
- {
- var packages = _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(stream).ToList();
-
- if (DateTime.UtcNow - _lastPackageUpdateTime > GetCacheLength())
- {
- UpdateCachedPackages(CancellationToken.None, false);
- }
-
- return packages;
- }
- }
- catch (Exception)
- {
-
- }
-
- _lastPackageUpdateTime = DateTime.MinValue;
- await UpdateCachedPackages(cancellationToken, true).ConfigureAwait(false);
- using (var stream = _fileSystem.OpenRead(PackageCachePath))
- {
- return _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(stream).ToList();
- }
- }
-
- private string PackageCachePath
- {
- get { return Path.Combine(_appPaths.CachePath, "serverpackages.json"); }
- }
-
- private readonly SemaphoreSlim _updateSemaphore = new SemaphoreSlim(1, 1);
- private async Task UpdateCachedPackages(CancellationToken cancellationToken, bool throwErrors)
- {
- await _updateSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
-
- try
- {
- if (DateTime.UtcNow - _lastPackageUpdateTime < GetCacheLength())
- {
- return;
- }
-
- var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions
- {
- Url = MbAdmin.HttpUrl + "service/MB3Packages.json",
- CancellationToken = cancellationToken,
- Progress = new Progress<Double>()
-
- }).ConfigureAwait(false);
-
- _fileSystem.CreateDirectory(Path.GetDirectoryName(PackageCachePath));
-
- _fileSystem.CopyFile(tempFile, PackageCachePath, true);
- _lastPackageUpdateTime = DateTime.UtcNow;
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error updating package cache", ex);
-
- if (throwErrors)
- {
- throw;
- }
- }
- finally
- {
- _updateSemaphore.Release();
- }
- }
-
- private TimeSpan GetCacheLength()
- {
- switch (_config.CommonConfiguration.SystemUpdateLevel)
- {
- case PackageVersionClass.Beta:
- return TimeSpan.FromMinutes(30);
- case PackageVersionClass.Dev:
- return TimeSpan.FromMinutes(3);
- default:
- return TimeSpan.FromHours(24);
- }
- }
-
- protected IEnumerable<PackageInfo> FilterPackages(List<PackageInfo> packages)
- {
- foreach (var package in packages)
- {
- package.versions = package.versions.Where(v => !string.IsNullOrWhiteSpace(v.sourceUrl))
- .OrderByDescending(GetPackageVersion).ToList();
- }
-
- // Remove packages with no versions
- packages = packages.Where(p => p.versions.Any()).ToList();
-
- return packages;
- }
-
- protected IEnumerable<PackageInfo> FilterPackages(List<PackageInfo> packages, string packageType, Version applicationVersion)
- {
- foreach (var package in packages)
- {
- package.versions = package.versions.Where(v => !string.IsNullOrWhiteSpace(v.sourceUrl))
- .OrderByDescending(GetPackageVersion).ToList();
- }
-
- if (!string.IsNullOrWhiteSpace(packageType))
- {
- packages = packages.Where(p => string.Equals(p.type, packageType, StringComparison.OrdinalIgnoreCase)).ToList();
- }
-
- // If an app version was supplied, filter the versions for each package to only include supported versions
- if (applicationVersion != null)
- {
- foreach (var package in packages)
- {
- package.versions = package.versions.Where(v => IsPackageVersionUpToDate(v, applicationVersion)).ToList();
- }
- }
-
- // Remove packages with no versions
- packages = packages.Where(p => p.versions.Any()).ToList();
-
- return packages;
- }
-
- /// <summary>
- /// Determines whether [is package version up to date] [the specified package version info].
- /// </summary>
- /// <param name="packageVersionInfo">The package version info.</param>
- /// <param name="currentServerVersion">The current server version.</param>
- /// <returns><c>true</c> if [is package version up to date] [the specified package version info]; otherwise, <c>false</c>.</returns>
- private bool IsPackageVersionUpToDate(PackageVersionInfo packageVersionInfo, Version currentServerVersion)
- {
- if (string.IsNullOrEmpty(packageVersionInfo.requiredVersionStr))
- {
- return true;
- }
-
- Version requiredVersion;
-
- return Version.TryParse(packageVersionInfo.requiredVersionStr, out requiredVersion) && currentServerVersion >= requiredVersion;
- }
-
- /// <summary>
- /// Gets the package.
- /// </summary>
- /// <param name="name">The name.</param>
- /// <param name="guid">The assembly guid</param>
- /// <param name="classification">The classification.</param>
- /// <param name="version">The version.</param>
- /// <returns>Task{PackageVersionInfo}.</returns>
- public async Task<PackageVersionInfo> GetPackage(string name, string guid, PackageVersionClass classification, Version version)
- {
- var packages = await GetAvailablePackages(CancellationToken.None).ConfigureAwait(false);
-
- var package = packages.FirstOrDefault(p => string.Equals(p.guid, guid ?? "none", StringComparison.OrdinalIgnoreCase))
- ?? packages.FirstOrDefault(p => p.name.Equals(name, StringComparison.OrdinalIgnoreCase));
-
- if (package == null)
- {
- return null;
- }
-
- return package.versions.FirstOrDefault(v => GetPackageVersion(v).Equals(version) && v.classification == classification);
- }
-
- /// <summary>
- /// Gets the latest compatible version.
- /// </summary>
- /// <param name="name">The name.</param>
- /// <param name="guid">The assembly guid if this is a plug-in</param>
- /// <param name="currentServerVersion">The current server version.</param>
- /// <param name="classification">The classification.</param>
- /// <returns>Task{PackageVersionInfo}.</returns>
- public async Task<PackageVersionInfo> GetLatestCompatibleVersion(string name, string guid, Version currentServerVersion, PackageVersionClass classification = PackageVersionClass.Release)
- {
- var packages = await GetAvailablePackages(CancellationToken.None).ConfigureAwait(false);
-
- return GetLatestCompatibleVersion(packages, name, guid, currentServerVersion, classification);
- }
-
- /// <summary>
- /// Gets the latest compatible version.
- /// </summary>
- /// <param name="availablePackages">The available packages.</param>
- /// <param name="name">The name.</param>
- /// <param name="currentServerVersion">The current server version.</param>
- /// <param name="classification">The classification.</param>
- /// <returns>PackageVersionInfo.</returns>
- public PackageVersionInfo GetLatestCompatibleVersion(IEnumerable<PackageInfo> availablePackages, string name, string guid, Version currentServerVersion, PackageVersionClass classification = PackageVersionClass.Release)
- {
- var package = availablePackages.FirstOrDefault(p => string.Equals(p.guid, guid ?? "none", StringComparison.OrdinalIgnoreCase))
- ?? availablePackages.FirstOrDefault(p => p.name.Equals(name, StringComparison.OrdinalIgnoreCase));
-
- if (package == null)
- {
- return null;
- }
-
- return package.versions
- .OrderByDescending(GetPackageVersion)
- .FirstOrDefault(v => v.classification <= classification && IsPackageVersionUpToDate(v, currentServerVersion));
- }
-
- /// <summary>
- /// Gets the available plugin updates.
- /// </summary>
- /// <param name="applicationVersion">The current server version.</param>
- /// <param name="withAutoUpdateEnabled">if set to <c>true</c> [with auto update enabled].</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task{IEnumerable{PackageVersionInfo}}.</returns>
- public async Task<IEnumerable<PackageVersionInfo>> GetAvailablePluginUpdates(Version applicationVersion, bool withAutoUpdateEnabled, CancellationToken cancellationToken)
- {
- var catalog = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false);
-
- var plugins = _applicationHost.Plugins.ToList();
-
- if (withAutoUpdateEnabled)
- {
- plugins = plugins
- .Where(p => _config.CommonConfiguration.EnableAutoUpdate)
- .ToList();
- }
-
- // Figure out what needs to be installed
- var packages = plugins.Select(p =>
- {
- var latestPluginInfo = GetLatestCompatibleVersion(catalog, p.Name, p.Id.ToString(), applicationVersion, _config.CommonConfiguration.SystemUpdateLevel);
-
- return latestPluginInfo != null && GetPackageVersion(latestPluginInfo) > p.Version ? latestPluginInfo : null;
-
- }).Where(i => i != null).ToList();
-
- return packages
- .Where(p => !string.IsNullOrWhiteSpace(p.sourceUrl) && !CompletedInstallations.Any(i => string.Equals(i.AssemblyGuid, p.guid, StringComparison.OrdinalIgnoreCase)));
- }
-
- /// <summary>
- /// Installs the package.
- /// </summary>
- /// <param name="package">The package.</param>
- /// <param name="isPlugin">if set to <c>true</c> [is plugin].</param>
- /// <param name="progress">The progress.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
- /// <exception cref="System.ArgumentNullException">package</exception>
- public async Task InstallPackage(PackageVersionInfo package, bool isPlugin, IProgress<double> progress, CancellationToken cancellationToken)
- {
- if (package == null)
- {
- throw new ArgumentNullException("package");
- }
-
- if (progress == null)
- {
- throw new ArgumentNullException("progress");
- }
-
- var installationInfo = new InstallationInfo
- {
- Id = Guid.NewGuid().ToString("N"),
- Name = package.name,
- AssemblyGuid = package.guid,
- UpdateClass = package.classification,
- Version = package.versionStr
- };
-
- var innerCancellationTokenSource = new CancellationTokenSource();
-
- var tuple = new Tuple<InstallationInfo, CancellationTokenSource>(installationInfo, innerCancellationTokenSource);
-
- // Add it to the in-progress list
- lock (CurrentInstallations)
- {
- CurrentInstallations.Add(tuple);
- }
-
- var innerProgress = new ActionableProgress<double>();
-
- // Whenever the progress updates, update the outer progress object and InstallationInfo
- innerProgress.RegisterAction(percent =>
- {
- progress.Report(percent);
-
- installationInfo.PercentComplete = percent;
- });
-
- var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, innerCancellationTokenSource.Token).Token;
-
- var installationEventArgs = new InstallationEventArgs
- {
- InstallationInfo = installationInfo,
- PackageVersionInfo = package
- };
-
- EventHelper.FireEventIfNotNull(PackageInstalling, this, installationEventArgs, _logger);
-
- try
- {
- await InstallPackageInternal(package, isPlugin, innerProgress, linkedToken).ConfigureAwait(false);
-
- lock (CurrentInstallations)
- {
- CurrentInstallations.Remove(tuple);
- }
-
- progress.Report(100);
-
- CompletedInstallations.Add(installationInfo);
-
- EventHelper.FireEventIfNotNull(PackageInstallationCompleted, this, installationEventArgs, _logger);
- }
- catch (OperationCanceledException)
- {
- lock (CurrentInstallations)
- {
- CurrentInstallations.Remove(tuple);
- }
-
- _logger.Info("Package installation cancelled: {0} {1}", package.name, package.versionStr);
-
- EventHelper.FireEventIfNotNull(PackageInstallationCancelled, this, installationEventArgs, _logger);
-
- throw;
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Package installation failed", ex);
-
- lock (CurrentInstallations)
- {
- CurrentInstallations.Remove(tuple);
- }
-
- EventHelper.FireEventIfNotNull(PackageInstallationFailed, this, new InstallationFailedEventArgs
- {
- InstallationInfo = installationInfo,
- Exception = ex
-
- }, _logger);
-
- throw;
- }
- finally
- {
- // Dispose the progress object and remove the installation from the in-progress list
- innerProgress.Dispose();
- tuple.Item2.Dispose();
- }
- }
-
- /// <summary>
- /// Installs the package internal.
- /// </summary>
- /// <param name="package">The package.</param>
- /// <param name="isPlugin">if set to <c>true</c> [is plugin].</param>
- /// <param name="progress">The progress.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
- private async Task InstallPackageInternal(PackageVersionInfo package, bool isPlugin, IProgress<double> progress, CancellationToken cancellationToken)
- {
- // Do the install
- await PerformPackageInstallation(progress, package, cancellationToken).ConfigureAwait(false);
-
- // Do plugin-specific processing
- if (isPlugin)
- {
- // Set last update time if we were installed before
- var plugin = _applicationHost.Plugins.FirstOrDefault(p => string.Equals(p.Id.ToString(), package.guid, StringComparison.OrdinalIgnoreCase))
- ?? _applicationHost.Plugins.FirstOrDefault(p => p.Name.Equals(package.name, StringComparison.OrdinalIgnoreCase));
-
- if (plugin != null)
- {
- OnPluginUpdated(plugin, package);
- }
- else
- {
- OnPluginInstalled(package);
- }
- }
- }
-
- private async Task PerformPackageInstallation(IProgress<double> progress, PackageVersionInfo package, CancellationToken cancellationToken)
- {
- // Target based on if it is an archive or single assembly
- // zip archives are assumed to contain directory structures relative to our ProgramDataPath
- var extension = Path.GetExtension(package.targetFilename);
- var isArchive = string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase) || string.Equals(extension, ".rar", StringComparison.OrdinalIgnoreCase) || string.Equals(extension, ".7z", StringComparison.OrdinalIgnoreCase);
- var target = Path.Combine(isArchive ? _appPaths.TempUpdatePath : _appPaths.PluginsPath, package.targetFilename);
-
- // Download to temporary file so that, if interrupted, it won't destroy the existing installation
- var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions
- {
- Url = package.sourceUrl,
- CancellationToken = cancellationToken,
- Progress = progress
-
- }).ConfigureAwait(false);
-
- cancellationToken.ThrowIfCancellationRequested();
-
- // Validate with a checksum
- var packageChecksum = string.IsNullOrWhiteSpace(package.checksum) ? Guid.Empty : new Guid(package.checksum);
- if (packageChecksum != Guid.Empty) // support for legacy uploads for now
- {
- using (var crypto = new MD5CryptoServiceProvider())
- using (var stream = new BufferedStream(_fileSystem.OpenRead(tempFile), 100000))
- {
- var check = Guid.Parse(BitConverter.ToString(crypto.ComputeHash(stream)).Replace("-", String.Empty));
- if (check != packageChecksum)
- {
- throw new ApplicationException(string.Format("Download validation failed for {0}. Probably corrupted during transfer.", package.name));
- }
- }
- }
-
- cancellationToken.ThrowIfCancellationRequested();
-
- // Success - move it to the real target
- try
- {
- _fileSystem.CreateDirectory(Path.GetDirectoryName(target));
- _fileSystem.CopyFile(tempFile, target, true);
- //If it is an archive - write out a version file so we know what it is
- if (isArchive)
- {
- File.WriteAllText(target + ".ver", package.versionStr);
- }
- }
- catch (IOException e)
- {
- _logger.ErrorException("Error attempting to move file from {0} to {1}", e, tempFile, target);
- throw;
- }
-
- try
- {
- _fileSystem.DeleteFile(tempFile);
- }
- catch (IOException e)
- {
- // Don't fail because of this
- _logger.ErrorException("Error deleting temp file {0]", e, tempFile);
- }
- }
-
- /// <summary>
- /// Uninstalls a plugin
- /// </summary>
- /// <param name="plugin">The plugin.</param>
- /// <exception cref="System.ArgumentException"></exception>
- public void UninstallPlugin(IPlugin plugin)
- {
- plugin.OnUninstalling();
-
- // Remove it the quick way for now
- _applicationHost.RemovePlugin(plugin);
-
- _fileSystem.DeleteFile(plugin.AssemblyFilePath);
-
- OnPluginUninstalled(plugin);
-
- _applicationHost.NotifyPendingRestart();
- }
-
- /// <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)
- {
- lock (CurrentInstallations)
- {
- foreach (var tuple in CurrentInstallations)
- {
- tuple.Item2.Dispose();
- }
-
- CurrentInstallations.Clear();
- }
- }
- }
-
- public void Dispose()
- {
- Dispose(true);
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config
deleted file mode 100644
index 4eacd0d725..0000000000
--- a/MediaBrowser.Common.Implementations/packages.config
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="NLog" version="4.3.10" targetFramework="net46" />
- <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
- <package id="SimpleInjector" version="3.2.4" targetFramework="net46" />
-</packages> \ No newline at end of file