diff --git a/Emby.Common.Implementations/BaseApplicationHost.cs b/Emby.Common.Implementations/BaseApplicationHost.cs deleted file mode 100644 index e7710162c..000000000 --- a/Emby.Common.Implementations/BaseApplicationHost.cs +++ /dev/null @@ -1,902 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Events; -using Emby.Common.Implementations.Devices; -using Emby.Common.Implementations.IO; -using Emby.Common.Implementations.ScheduledTasks; -using Emby.Common.Implementations.Serialization; -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.IO; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Serialization; -using MediaBrowser.Model.Updates; -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 Emby.Common.Implementations.Cryptography; -using Emby.Common.Implementations.Diagnostics; -using Emby.Common.Implementations.Net; -using Emby.Common.Implementations.EnvironmentInfo; -using Emby.Common.Implementations.Threading; -using MediaBrowser.Common; -using MediaBrowser.Model.Cryptography; -using MediaBrowser.Model.Diagnostics; -using MediaBrowser.Model.Net; -using MediaBrowser.Model.System; -using MediaBrowser.Model.Tasks; -using MediaBrowser.Model.Threading; - -namespace Emby.Common.Implementations -{ - /// - /// Class BaseApplicationHost - /// - /// The type of the T application paths type. - public abstract class BaseApplicationHost : IApplicationHost - where TApplicationPathsType : class, IApplicationPaths - { - /// - /// Occurs when [has pending restart changed]. - /// - public event EventHandler HasPendingRestartChanged; - - /// - /// Occurs when [application updated]. - /// - public event EventHandler> ApplicationUpdated; - - /// - /// Gets or sets a value indicating whether this instance has changes that require the entire application to restart. - /// - /// true if this instance has pending application restart; otherwise, false. - public bool HasPendingRestart { get; private set; } - - /// - /// Gets or sets the logger. - /// - /// The logger. - protected ILogger Logger { get; private set; } - - /// - /// Gets or sets the plugins. - /// - /// The plugins. - public IPlugin[] Plugins { get; protected set; } - - /// - /// Gets or sets the log manager. - /// - /// The log manager. - public ILogManager LogManager { get; protected set; } - - /// - /// Gets the application paths. - /// - /// The application paths. - protected TApplicationPathsType ApplicationPaths { get; private set; } - - /// - /// The json serializer - /// - public IJsonSerializer JsonSerializer { get; private set; } - - /// - /// The _XML serializer - /// - protected readonly IXmlSerializer XmlSerializer; - - /// - /// Gets assemblies that failed to load - /// - /// The failed assemblies. - public List FailedAssemblies { get; protected set; } - - /// - /// Gets all concrete types. - /// - /// All concrete types. - public Type[] AllConcreteTypes { get; protected set; } - - /// - /// The disposable parts - /// - protected readonly List DisposableParts = new List(); - - /// - /// Gets a value indicating whether this instance is first run. - /// - /// true if this instance is first run; otherwise, false. - public bool IsFirstRun { get; private set; } - - /// - /// Gets the kernel. - /// - /// The kernel. - protected ITaskManager TaskManager { get; private set; } - /// - /// Gets the HTTP client. - /// - /// The HTTP client. - public IHttpClient HttpClient { get; private set; } - /// - /// Gets the network manager. - /// - /// The network manager. - protected INetworkManager NetworkManager { get; private set; } - - /// - /// Gets the configuration manager. - /// - /// The configuration manager. - protected IConfigurationManager ConfigurationManager { get; private set; } - - public IFileSystem FileSystemManager { get; private set; } - - protected IIsoManager IsoManager { get; private set; } - - protected IProcessFactory ProcessFactory { get; private set; } - protected ITimerFactory TimerFactory { get; private set; } - protected ISocketFactory SocketFactory { get; private set; } - - /// - /// Gets the name. - /// - /// The name. - public abstract string Name { get; } - - protected ICryptoProvider CryptographyProvider = new CryptographyProvider(); - - protected IEnvironmentInfo EnvironmentInfo { get; private set; } - - private DeviceId _deviceId; - public string SystemId - { - get - { - if (_deviceId == null) - { - _deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId"), FileSystemManager); - } - - return _deviceId.Value; - } - } - - public PackageVersionClass SystemUpdateLevel - { - get - { - -#if BETA - return PackageVersionClass.Beta; -#endif - return PackageVersionClass.Release; - } - } - - public virtual string OperatingSystemDisplayName - { - get { return EnvironmentInfo.OperatingSystemName; } - } - - /// - /// The container - /// - protected readonly SimpleInjector.Container Container = new SimpleInjector.Container(); - - protected ISystemEvents SystemEvents { get; private set; } - protected IMemoryStreamFactory MemoryStreamFactory { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - protected BaseApplicationHost(TApplicationPathsType applicationPaths, - ILogManager logManager, - IFileSystem fileSystem, - IEnvironmentInfo environmentInfo, - ISystemEvents systemEvents, - IMemoryStreamFactory memoryStreamFactory, - INetworkManager networkManager) - { - NetworkManager = networkManager; - EnvironmentInfo = environmentInfo; - SystemEvents = systemEvents; - MemoryStreamFactory = memoryStreamFactory; - - // hack alert, until common can target .net core - BaseExtensions.CryptographyProvider = CryptographyProvider; - - XmlSerializer = new MyXmlSerializer(fileSystem, logManager.GetLogger("XmlSerializer")); - FailedAssemblies = new List(); - - ApplicationPaths = applicationPaths; - LogManager = logManager; - FileSystemManager = fileSystem; - - ConfigurationManager = GetConfigurationManager(); - - // Initialize this early in case the -v command line option is used - Logger = LogManager.GetLogger("App"); - } - - /// - /// Inits this instance. - /// - /// Task. - public virtual async Task Init(IProgress progress) - { - progress.Report(1); - - JsonSerializer = CreateJsonSerializer(); - - 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(); - 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 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("64-Bit OS: {0}", Environment.Is64BitOperatingSystem)); - builder.AppendLine(string.Format("64-Bit Process: {0}", Environment.Is64BitProcess)); - - 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("Processor count: {0}", Environment.ProcessorCount)); - builder.AppendLine(string.Format("Program data path: {0}", appPaths.ProgramDataPath)); - builder.AppendLine(string.Format("Application directory: {0}", appPaths.ProgramSystemPath)); - - return builder; - } - - protected abstract IJsonSerializer CreateJsonSerializer(); - - 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); - } - } - - /// - /// Installs the iso mounters. - /// - /// The cancellation token. - /// Task. - private async Task InstallIsoMounters(CancellationToken cancellationToken) - { - var list = new List(); - - foreach (var isoMounter in GetExports()) - { - 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); - } - - /// - /// Runs the startup tasks. - /// - /// Task. - public virtual Task RunStartupTasks() - { - Resolve().AddTasks(GetExports(false)); - - ConfigureAutorun(); - - ConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated; - - return Task.FromResult(true); - } - - /// - /// Configures the autorun. - /// - private void ConfigureAutorun() - { - try - { - ConfigureAutoRunAtStartup(ConfigurationManager.CommonConfiguration.RunAtStartup); - } - catch (Exception ex) - { - Logger.ErrorException("Error configuring autorun", ex); - } - } - - /// - /// Gets the composable part assemblies. - /// - /// IEnumerable{Assembly}. - protected abstract IEnumerable GetComposablePartAssemblies(); - - /// - /// Gets the configuration manager. - /// - /// IConfigurationManager. - protected abstract IConfigurationManager GetConfigurationManager(); - - /// - /// Finds the parts. - /// - protected virtual void FindParts() - { - ConfigurationManager.AddParts(GetExports()); - Plugins = GetExports().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; - } - - /// - /// Discovers the types. - /// - 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(); - } - - /// - /// Registers resources that classes will depend on - /// - /// Task. - protected virtual Task RegisterResources(IProgress progress) - { - RegisterSingleInstance(ConfigurationManager); - RegisterSingleInstance(this); - - RegisterSingleInstance(ApplicationPaths); - - TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, LogManager.GetLogger("TaskManager"), FileSystemManager, SystemEvents); - - RegisterSingleInstance(JsonSerializer); - RegisterSingleInstance(XmlSerializer); - RegisterSingleInstance(MemoryStreamFactory); - RegisterSingleInstance(SystemEvents); - - RegisterSingleInstance(LogManager); - RegisterSingleInstance(Logger); - - RegisterSingleInstance(TaskManager); - RegisterSingleInstance(EnvironmentInfo); - - RegisterSingleInstance(FileSystemManager); - - HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager, MemoryStreamFactory, GetDefaultUserAgent); - RegisterSingleInstance(HttpClient); - - RegisterSingleInstance(NetworkManager); - - IsoManager = new IsoManager(); - RegisterSingleInstance(IsoManager); - - ProcessFactory = new ProcessFactory(); - RegisterSingleInstance(ProcessFactory); - - TimerFactory = new TimerFactory(); - RegisterSingleInstance(TimerFactory); - - SocketFactory = new SocketFactory(LogManager.GetLogger("SocketFactory")); - RegisterSingleInstance(SocketFactory); - - RegisterSingleInstance(CryptographyProvider); - - return Task.FromResult(true); - } - - private string GetDefaultUserAgent() - { - var name = FormatAttribute(Name); - - return name + "/" + ApplicationVersion.ToString(); - } - - private string FormatAttribute(string str) - { - var arr = str.ToCharArray(); - - arr = Array.FindAll(arr, (c => (char.IsLetterOrDigit(c) - || char.IsWhiteSpace(c)))); - - var result = new string(arr); - - if (string.IsNullOrWhiteSpace(result)) - { - result = "Emby"; - } - - return result; - } - - /// - /// Gets a list of types within an assembly - /// This will handle situations that would normally throw an exception - such as a type within the assembly that depends on some other non-existant reference - /// - /// The assembly. - /// IEnumerable{Type}. - /// assembly - protected List GetTypes(Assembly assembly) - { - if (assembly == null) - { - return new List(); - } - - try - { - // This null checking really shouldn't be needed but adding it due to some - // unhandled exceptions in mono 5.0 that are a little hard to hunt down - var types = assembly.GetTypes() ?? new Type[] { }; - return types.Where(t => t != null).ToList(); - } - catch (ReflectionTypeLoadException ex) - { - if (ex.LoaderExceptions != null) - { - foreach (var loaderException in ex.LoaderExceptions) - { - if (loaderException != null) - { - Logger.Error("LoaderException: " + loaderException.Message); - } - } - } - - // If it fails we can still get a list of the Types it was able to resolve - var types = ex.Types ?? new Type[] { }; - return types.Where(t => t != null).ToList(); - } - catch (Exception ex) - { - Logger.ErrorException("Error loading types from assembly", ex); - - return new List(); - } - } - - /// - /// Creates an instance of type and resolves all constructor dependancies - /// - /// The type. - /// System.Object. - public object CreateInstance(Type type) - { - try - { - return Container.GetInstance(type); - } - catch (Exception ex) - { - Logger.ErrorException("Error creating {0}", ex, type.FullName); - - throw; - } - } - - /// - /// Creates the instance safe. - /// - /// The type. - /// System.Object. - 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; - } - } - - /// - /// Registers the specified obj. - /// - /// - /// The obj. - /// if set to true [manage lifetime]. - protected void RegisterSingleInstance(T obj, bool manageLifetime = true) - where T : class - { - Container.RegisterSingleton(obj); - - if (manageLifetime) - { - var disposable = obj as IDisposable; - - if (disposable != null) - { - DisposableParts.Add(disposable); - } - } - } - - /// - /// Registers the single instance. - /// - /// - /// The func. - protected void RegisterSingleInstance(Func func) - where T : class - { - Container.RegisterSingleton(func); - } - - /// - /// Resolves this instance. - /// - /// - /// ``0. - public T Resolve() - { - return (T)Container.GetRegistration(typeof(T), true).GetInstance(); - } - - /// - /// Resolves this instance. - /// - /// - /// ``0. - public T TryResolve() - { - var result = Container.GetRegistration(typeof(T), false); - - if (result == null) - { - return default(T); - } - return (T)result.GetInstance(); - } - - /// - /// Loads the assembly. - /// - /// The file. - /// Assembly. - protected Assembly LoadAssembly(string file) - { - try - { - return Assembly.Load(File.ReadAllBytes(file)); - } - catch (Exception ex) - { - FailedAssemblies.Add(file); - Logger.ErrorException("Error loading assembly {0}", ex, file); - return null; - } - } - - /// - /// Gets the export types. - /// - /// - /// IEnumerable{Type}. - public IEnumerable GetExportTypes() - { - var currentType = typeof(T); - - return AllConcreteTypes.Where(currentType.IsAssignableFrom); - } - - /// - /// Gets the exports. - /// - /// - /// if set to true [manage liftime]. - /// IEnumerable{``0}. - public IEnumerable GetExports(bool manageLiftime = true) - { - var parts = GetExportTypes() - .Select(CreateInstanceSafe) - .Where(i => i != null) - .Cast() - .ToList(); - - if (manageLiftime) - { - lock (DisposableParts) - { - DisposableParts.AddRange(parts.OfType()); - } - } - - return parts; - } - - /// - /// Gets the application version. - /// - /// The application version. - public abstract Version ApplicationVersion { get; } - - /// - /// Handles the ConfigurationUpdated event of the ConfigurationManager control. - /// - /// The source of the event. - /// The instance containing the event data. - /// - protected virtual void OnConfigurationUpdated(object sender, EventArgs e) - { - ConfigureAutorun(); - } - - protected abstract void ConfigureAutoRunAtStartup(bool autorun); - - /// - /// Removes the plugin. - /// - /// The plugin. - public void RemovePlugin(IPlugin plugin) - { - var list = Plugins.ToList(); - list.Remove(plugin); - Plugins = list.ToArray(); - } - - /// - /// Gets a value indicating whether this instance can self restart. - /// - /// true if this instance can self restart; otherwise, false. - public abstract bool CanSelfRestart { get; } - - /// - /// Notifies that the kernel that a change has been made that requires a restart - /// - public void NotifyPendingRestart() - { - Logger.Info("App needs to be restarted."); - - var changed = !HasPendingRestart; - - HasPendingRestart = true; - - if (changed) - { - EventHelper.QueueEventIfNotNull(HasPendingRestartChanged, this, EventArgs.Empty, Logger); - } - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - 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); - } - } - } - } - - /// - /// Restarts this instance. - /// - public abstract Task Restart(); - - /// - /// Gets or sets a value indicating whether this instance can self update. - /// - /// true if this instance can self update; otherwise, false. - public virtual bool CanSelfUpdate - { - get - { - return false; - } - } - - /// - /// Checks for update. - /// - /// The cancellation token. - /// The progress. - /// Task{CheckForUpdateResult}. - public abstract Task CheckForApplicationUpdate(CancellationToken cancellationToken, - IProgress progress); - - /// - /// Updates the application. - /// - /// The package that contains the update - /// The cancellation token. - /// The progress. - /// Task. - public abstract Task UpdateApplication(PackageVersionInfo package, CancellationToken cancellationToken, - IProgress progress); - - /// - /// Shuts down. - /// - public abstract Task Shutdown(); - - /// - /// Called when [application updated]. - /// - /// The package. - protected void OnApplicationUpdated(PackageVersionInfo package) - { - Logger.Info("Application has been updated to version {0}", package.versionStr); - - EventHelper.FireEventIfNotNull(ApplicationUpdated, this, new GenericEventArgs - { - Argument = package - - }, Logger); - - NotifyPendingRestart(); - } - } -} diff --git a/Emby.Common.Implementations/Emby.Common.Implementations.csproj b/Emby.Common.Implementations/Emby.Common.Implementations.csproj deleted file mode 100644 index cbd077e19..000000000 --- a/Emby.Common.Implementations/Emby.Common.Implementations.csproj +++ /dev/null @@ -1,452 +0,0 @@ - - - - - Debug - AnyCPU - {1E37A338-9F57-4B70-BD6D-BB9C591E319B} - Library - Properties - Emby.Common.Implementations - Emby.Common.Implementations - v4.6 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\NLog.4.4.12\lib\net45\NLog.dll - - - ..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll - True - - - ..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll - True - - - ..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll - - - - - - - - - - - - - Properties\SharedVersion.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {9142eefa-7570-41e1-bfcc-468bb571af2f} - MediaBrowser.Common - - - {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} - MediaBrowser.Model - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Emby.Common.Implementations/Logging/NLogger.cs b/Emby.Common.Implementations/Logging/NLogger.cs deleted file mode 100644 index 8abd3d0d9..000000000 --- a/Emby.Common.Implementations/Logging/NLogger.cs +++ /dev/null @@ -1,224 +0,0 @@ -using MediaBrowser.Model.Logging; -using System; -using System.Text; - -namespace Emby.Common.Implementations.Logging -{ - /// - /// Class NLogger - /// - public class NLogger : ILogger - { - /// - /// The _logger - /// - private readonly NLog.Logger _logger; - - private readonly ILogManager _logManager; - - /// - /// The _lock object - /// - private static readonly object LockObject = new object(); - - /// - /// Initializes a new instance of the class. - /// - /// The name. - /// The log manager. - public NLogger(string name, ILogManager logManager) - { - _logManager = logManager; - lock (LockObject) - { - _logger = NLog.LogManager.GetLogger(name); - } - } - - /// - /// Infoes the specified message. - /// - /// The message. - /// The param list. - public void Info(string message, params object[] paramList) - { - _logger.Info(message, paramList); - } - - /// - /// Errors the specified message. - /// - /// The message. - /// The param list. - public void Error(string message, params object[] paramList) - { - _logger.Error(message, paramList); - } - - /// - /// Warns the specified message. - /// - /// The message. - /// The param list. - public void Warn(string message, params object[] paramList) - { - _logger.Warn(message, paramList); - } - - /// - /// Debugs the specified message. - /// - /// The message. - /// The param list. - public void Debug(string message, params object[] paramList) - { - if (_logManager.LogSeverity == LogSeverity.Info) - { - return; - } - - _logger.Debug(message, paramList); - } - - /// - /// Logs the exception. - /// - /// The message. - /// The exception. - /// The param list. - /// - public void ErrorException(string message, Exception exception, params object[] paramList) - { - LogException(LogSeverity.Error, message, exception, paramList); - } - - /// - /// Logs the exception. - /// - /// The level. - /// The message. - /// The exception. - /// The param list. - 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); - } - - /// - /// Formats the message. - /// - /// The message. - /// The param list. - /// System.String. - 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; - } - - /// - /// Logs the multiline. - /// - /// The message. - /// The severity. - /// Content of the additional. - 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); - } - - /// - /// Gets the log level. - /// - /// The severity. - /// NLog.LogLevel. - 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()); - } - } - - /// - /// Logs the specified severity. - /// - /// The severity. - /// The message. - /// The param list. - public void Log(LogSeverity severity, string message, params object[] paramList) - { - _logger.Log(GetLogLevel(severity), message, paramList); - } - - /// - /// Fatals the specified message. - /// - /// The message. - /// The param list. - public void Fatal(string message, params object[] paramList) - { - _logger.Fatal(message, paramList); - } - - /// - /// Fatals the exception. - /// - /// The message. - /// The exception. - /// The param list. - public void FatalException(string message, Exception exception, params object[] paramList) - { - LogException(LogSeverity.Fatal, message, exception, paramList); - } - } -} diff --git a/Emby.Common.Implementations/Logging/NlogManager.cs b/Emby.Common.Implementations/Logging/NlogManager.cs deleted file mode 100644 index 4446e2cdb..000000000 --- a/Emby.Common.Implementations/Logging/NlogManager.cs +++ /dev/null @@ -1,554 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Xml; -using NLog; -using NLog.Config; -using NLog.Filters; -using NLog.Targets; -using NLog.Targets.Wrappers; -using MediaBrowser.Model.Logging; - -namespace Emby.Common.Implementations.Logging -{ - /// - /// Class NlogManager - /// - public class NlogManager : ILogManager - { - #region Private Fields - - private LogSeverity _severity = LogSeverity.Debug; - - /// - /// Gets or sets the log directory. - /// - /// The log directory. - private readonly string LogDirectory; - - /// - /// Gets or sets the log file prefix. - /// - /// The log file prefix. - private readonly string LogFilePrefix; - - #endregion - - #region Event Declarations - - /// - /// Occurs when [logger loaded]. - /// - public event EventHandler LoggerLoaded; - - #endregion - - #region Public Properties - - /// - /// Gets the log file path. - /// - /// The log file path. - public string LogFilePath { get; private set; } - - /// - /// Gets or sets the exception message prefix. - /// - /// The exception message prefix. - public string ExceptionMessagePrefix { get; set; } - - public string NLogConfigurationFilePath { get; set; } - - public LogSeverity LogSeverity - { - - get - { - return _severity; - } - - set - { - DebugFileWriter( - LogDirectory, String.Format( - "SET LogSeverity, _severity = [{0}], value = [{1}]", - _severity.ToString(), - value.ToString() - )); - - var changed = _severity != value; - - _severity = value; - - if (changed) - { - UpdateLogLevel(value); - } - - } - } - - #endregion - - #region Constructor(s) - - /// - /// Initializes a new instance of the class. - /// - /// The log directory. - /// The log file name prefix. - public NlogManager(string logDirectory, string logFileNamePrefix) - { - DebugFileWriter( - logDirectory, String.Format( - "NlogManager constructor called, logDirectory is [{0}], logFileNamePrefix is [{1}], _severity is [{2}].", - logDirectory, - logFileNamePrefix, - _severity.ToString() - )); - - LogDirectory = logDirectory; - LogFilePrefix = logFileNamePrefix; - - LogManager.Configuration = new LoggingConfiguration(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The log directory. - /// The log file name prefix. - public NlogManager(string logDirectory, string logFileNamePrefix, LogSeverity initialSeverity) : this(logDirectory, logFileNamePrefix) - { - _severity = initialSeverity; - - DebugFileWriter( - logDirectory, String.Format( - "NlogManager constructor called, logDirectory is [{0}], logFileNamePrefix is [{1}], _severity is [{2}].", - logDirectory, - logFileNamePrefix, - _severity.ToString() - )); - } - - #endregion - - #region Private Methods - - /// - /// Adds the file target. - /// - /// The path. - /// The level. - private void AddFileTarget(string path, LogSeverity level) - { - - DebugFileWriter( - LogDirectory, String.Format( - "AddFileTarget called, path = [{0}], level = [{1}].", - path, - level.ToString() - )); - - RemoveTarget("ApplicationLogFileWrapper"); - - // https://github.com/NLog/NLog/wiki/Performance - var wrapper = new AsyncTargetWrapper - { - OverflowAction = AsyncTargetWrapperOverflowAction.Block, - QueueLimit = 10000, - BatchSize = 500, - TimeToSleepBetweenBatches = 50 - }; - - wrapper.Name = "ApplicationLogFileWrapper"; - - var logFile = new FileTarget - { - FileName = path, - Layout = "${longdate} ${level} ${logger}: ${message}", - KeepFileOpen = true, - ConcurrentWrites = false - }; - - logFile.Name = "ApplicationLogFile"; - - wrapper.WrappedTarget = logFile; - - AddLogTarget(wrapper, level); - - } - - /// - /// Gets the log level. - /// - /// The severity. - /// LogLevel. - /// Unrecognized LogSeverity - 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"); - } - } - - private void UpdateLogLevel(LogSeverity newLevel) - { - DebugFileWriter( - LogDirectory, String.Format( - "UpdateLogLevel called, newLevel = [{0}].", - newLevel.ToString() - )); - - 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); - } - } - } - } - - private void AddCustomFilters(string defaultLoggerNamePattern, LoggingRule defaultRule) - { - DebugFileWriter( - LogDirectory, String.Format( - "AddCustomFilters called, defaultLoggerNamePattern = [{0}], defaultRule.LoggerNamePattern = [{1}].", - defaultLoggerNamePattern, - defaultRule.LoggerNamePattern - )); - - try - { - var customConfig = new NLog.Config.XmlLoggingConfiguration(NLogConfigurationFilePath); - - DebugFileWriter( - LogDirectory, String.Format( - "Custom Configuration Loaded, Rule Count = [{0}].", - customConfig.LoggingRules.Count.ToString() - )); - - foreach (var customRule in customConfig.LoggingRules) - { - - DebugFileWriter( - LogDirectory, String.Format( - "Read Custom Rule, LoggerNamePattern = [{0}], Targets = [{1}].", - customRule.LoggerNamePattern, - string.Join(",", customRule.Targets.Select(x => x.Name).ToList()) - )); - - if (customRule.LoggerNamePattern.Equals(defaultLoggerNamePattern)) - { - - if (customRule.Targets.Any((arg) => arg.Name.Equals(defaultRule.Targets.First().Name))) - { - - DebugFileWriter( - LogDirectory, String.Format( - "Custom rule filters can be applied to this target, Filter Count = [{0}].", - customRule.Filters.Count.ToString() - )); - - foreach (ConditionBasedFilter customFilter in customRule.Filters) - { - - DebugFileWriter( - LogDirectory, String.Format( - "Read Custom Filter, Filter = [{0}], Action = [{1}], Type = [{2}].", - customFilter.Condition.ToString(), - customFilter.Action.ToString(), - customFilter.GetType().ToString() - )); - - defaultRule.Filters.Add(customFilter); - - } - } - else - { - - DebugFileWriter( - LogDirectory, String.Format( - "Ignoring custom rule as [Target] does not match." - )); - - } - - } - else - { - - DebugFileWriter( - LogDirectory, String.Format( - "Ignoring custom rule as [LoggerNamePattern] does not match." - )); - - } - } - } - catch (Exception ex) - { - // Intentionally do nothing, prevent issues affecting normal execution. - DebugFileWriter( - LogDirectory, String.Format( - "Exception in AddCustomFilters, ex.Message = [{0}].", - ex.Message - ) - ); - - } - } - - #endregion - - #region Public Methods - - /// - /// Gets the logger. - /// - /// The name. - /// ILogger. - public MediaBrowser.Model.Logging.ILogger GetLogger(string name) - { - - DebugFileWriter( - LogDirectory, String.Format( - "GetLogger called, name = [{0}].", - name - )); - - return new NLogger(name, this); - - } - - /// - /// Adds the log target. - /// - /// The target. - /// The level. - public void AddLogTarget(Target target, LogSeverity level) - { - - DebugFileWriter( - LogDirectory, String.Format( - "AddLogTarget called, target.Name = [{0}], level = [{1}].", - target.Name, - level.ToString() - )); - - string loggerNamePattern = "*"; - var config = LogManager.Configuration; - var rule = new LoggingRule(loggerNamePattern, GetLogLevel(level), target); - - config.AddTarget(target.Name, target); - - AddCustomFilters(loggerNamePattern, rule); - - config.LoggingRules.Add(rule); - - LogManager.Configuration = config; - - } - - /// - /// Removes the target. - /// - /// The name. - public void RemoveTarget(string name) - { - - DebugFileWriter( - LogDirectory, String.Format( - "RemoveTarget called, name = [{0}].", - 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; - } - } - - public void AddConsoleOutput() - { - - DebugFileWriter( - LogDirectory, String.Format( - "AddConsoleOutput called." - )); - - 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() - { - - DebugFileWriter( - LogDirectory, String.Format( - "RemoveConsoleOutput called." - )); - - RemoveTarget("ConsoleTargetWrapper"); - - } - - /// - /// Reloads the logger, maintaining the current log level. - /// - public void ReloadLogger() - { - ReloadLogger(LogSeverity); - } - - /// - /// Reloads the logger, using the specified logging level. - /// - /// The level. - public void ReloadLogger(LogSeverity level) - { - - DebugFileWriter( - LogDirectory, String.Format( - "ReloadLogger called, level = [{0}], LogFilePath (existing) = [{1}].", - level.ToString(), - LogFilePath - )); - - LogFilePath = Path.Combine(LogDirectory, LogFilePrefix + "-" + decimal.Floor(DateTime.Now.Ticks / 10000000) + ".txt"); - - Directory.CreateDirectory(Path.GetDirectoryName(LogFilePath)); - - AddFileTarget(LogFilePath, level); - - LogSeverity = level; - - if (LoggerLoaded != null) - { - try - { - - DebugFileWriter( - LogDirectory, String.Format( - "ReloadLogger called, raised event LoggerLoaded." - )); - - LoggerLoaded(this, EventArgs.Empty); - - } - catch (Exception ex) - { - GetLogger("Logger").ErrorException("Error in LoggerLoaded event", ex); - } - } - } - - /// - /// Flushes this instance. - /// - public void Flush() - { - - DebugFileWriter( - LogDirectory, String.Format( - "Flush called." - )); - - LogManager.Flush(); - - } - - #endregion - - #region Conditional Debug Methods - - /// - /// DEBUG: Standalone method to write out debug to assist with logger development/troubleshooting. - /// - /// The output file will be written to the server's log directory. - /// Calls to the method are safe and will never throw any exceptions. - /// Method calls will be omitted unless the library is compiled with DEBUG defined. - /// - /// - private static void DebugFileWriter(string logDirectory, string message) - { -#if DEBUG - try - { - - System.IO.File.AppendAllText( - Path.Combine(logDirectory, "NlogManager.txt"), - String.Format( - "{0} : {1}{2}", - System.DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), - message, - System.Environment.NewLine - ) - ); - - } - catch (Exception ex) - { - // Intentionally do nothing, prevent issues affecting normal execution. - } -#endif - } - #endregion - } -} \ No newline at end of file diff --git a/Emby.Common.Implementations/Properties/AssemblyInfo.cs b/Emby.Common.Implementations/Properties/AssemblyInfo.cs deleted file mode 100644 index 787f18997..000000000 --- a/Emby.Common.Implementations/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Emby.Common.Implementations")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Emby.Common.Implementations")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[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("1e37a338-9f57-4b70-bd6d-bb9c591e319b")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] \ No newline at end of file diff --git a/Emby.Common.Implementations/packages.config b/Emby.Common.Implementations/packages.config deleted file mode 100644 index eb8fd586e..000000000 --- a/Emby.Common.Implementations/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index 71a049394..64e76276c 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -661,7 +661,7 @@ namespace Emby.Dlna.Didl return; } - XmlAttribute secAttribute = null; + MediaBrowser.Model.Dlna.XmlAttribute secAttribute = null; foreach (var attribute in _profile.XmlRootAttributes) { if (string.Equals(attribute.Name, "xmlns:sec", StringComparison.OrdinalIgnoreCase)) diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index 16108522c..a6facab7d 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -158,7 +158,7 @@ namespace Emby.Dlna.Main { if (_communicationsServer == null) { - var enableMultiSocketBinding = _environmentInfo.OperatingSystem == OperatingSystem.Windows; + var enableMultiSocketBinding = _environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows; _communicationsServer = new SsdpCommunicationsServer(_socketFactory, _networkManager, _logger, enableMultiSocketBinding) { diff --git a/Emby.Drawing.Skia/SkiaEncoder.cs b/Emby.Drawing.Skia/SkiaEncoder.cs index 071c40c29..77ab1919a 100644 --- a/Emby.Drawing.Skia/SkiaEncoder.cs +++ b/Emby.Drawing.Skia/SkiaEncoder.cs @@ -74,8 +74,9 @@ namespace Emby.Drawing.Skia return typeof(SKBitmap).GetTypeInfo().Assembly.GetName().Version.ToString(); } - private static bool IsWhiteSpace(SKColor color) + private static bool IsTransparent(SKColor color) { + return (color.Red == 255 && color.Green == 255 && color.Blue == 255) || color.Alpha == 0; } @@ -96,11 +97,11 @@ namespace Emby.Drawing.Skia } } - private static bool IsAllWhiteRow(SKBitmap bmp, int row) + private static bool IsTransparentRow(SKBitmap bmp, int row) { for (var i = 0; i < bmp.Width; ++i) { - if (!IsWhiteSpace(bmp.GetPixel(i, row))) + if (!IsTransparent(bmp.GetPixel(i, row))) { return false; } @@ -108,11 +109,11 @@ namespace Emby.Drawing.Skia return true; } - private static bool IsAllWhiteColumn(SKBitmap bmp, int col) + private static bool IsTransparentColumn(SKBitmap bmp, int col) { for (var i = 0; i < bmp.Height; ++i) { - if (!IsWhiteSpace(bmp.GetPixel(col, i))) + if (!IsTransparent(bmp.GetPixel(col, i))) { return false; } @@ -125,7 +126,7 @@ namespace Emby.Drawing.Skia var topmost = 0; for (int row = 0; row < bitmap.Height; ++row) { - if (IsAllWhiteRow(bitmap, row)) + if (IsTransparentRow(bitmap, row)) topmost = row + 1; else break; } @@ -133,7 +134,7 @@ namespace Emby.Drawing.Skia int bottommost = bitmap.Height; for (int row = bitmap.Height - 1; row >= 0; --row) { - if (IsAllWhiteRow(bitmap, row)) + if (IsTransparentRow(bitmap, row)) bottommost = row; else break; } @@ -141,7 +142,7 @@ namespace Emby.Drawing.Skia int leftmost = 0, rightmost = bitmap.Width; for (int col = 0; col < bitmap.Width; ++col) { - if (IsAllWhiteColumn(bitmap, col)) + if (IsTransparentColumn(bitmap, col)) leftmost = col + 1; else break; @@ -149,7 +150,7 @@ namespace Emby.Drawing.Skia for (int col = bitmap.Width - 1; col >= 0; --col) { - if (IsAllWhiteColumn(bitmap, col)) + if (IsTransparentColumn(bitmap, col)) rightmost = col; else break; diff --git a/Emby.Drawing/Emby.Drawing.csproj b/Emby.Drawing/Emby.Drawing.csproj index 90418f631..c5dd671a8 100644 --- a/Emby.Drawing/Emby.Drawing.csproj +++ b/Emby.Drawing/Emby.Drawing.csproj @@ -32,11 +32,6 @@ prompt 4 - - - ..\ThirdParty\taglib\TagLib.Portable.dll - - Properties\SharedVersion.cs diff --git a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs index 54d1d5302..1e63aa1a6 100644 --- a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs +++ b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs @@ -13,15 +13,12 @@ namespace Emby.Server.Implementations.AppBase /// /// Initializes a new instance of the class. /// - protected BaseApplicationPaths(string programDataPath, string appFolderPath, Action createDirectoryFn) + protected BaseApplicationPaths(string programDataPath, string appFolderPath) { ProgramDataPath = programDataPath; ProgramSystemPath = appFolderPath; - CreateDirectoryFn = createDirectoryFn; } - protected Action CreateDirectoryFn; - public string ProgramDataPath { get; private set; } /// @@ -45,7 +42,7 @@ namespace Emby.Server.Implementations.AppBase { _dataDirectory = Path.Combine(ProgramDataPath, "data"); - CreateDirectoryFn(_dataDirectory); + Directory.CreateDirectory(_dataDirectory); } return _dataDirectory; @@ -152,7 +149,7 @@ namespace Emby.Server.Implementations.AppBase { _cachePath = Path.Combine(ProgramDataPath, "cache"); - CreateDirectoryFn(_cachePath); + Directory.CreateDirectory(_cachePath); } return _cachePath; diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 7f893d8f7..bc88d652c 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1,11 +1,5 @@ using Emby.Common.Implementations; -using Emby.Common.Implementations.Archiving; -using Emby.Common.Implementations.IO; -using Emby.Common.Implementations.Reflection; -using Emby.Common.Implementations.ScheduledTasks; using Emby.Common.Implementations.Serialization; -using Emby.Common.Implementations.TextEncoding; -using Emby.Common.Implementations.Xml; using Emby.Dlna; using Emby.Dlna.ConnectionManager; using Emby.Dlna.ContentDirectory; @@ -110,12 +104,29 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using System.Net; using System.Reflection; +using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; +using System.Text; using System.Threading; using System.Threading.Tasks; +using Emby.Server.Core.Cryptography; +using Emby.Server.Implementations.Archiving; +using Emby.Server.Implementations.Cryptography; +using Emby.Server.Implementations.Diagnostics; +using Emby.Server.Implementations.Net; +using Emby.Server.Implementations.Reflection; +using Emby.Server.Implementations.ScheduledTasks; +using Emby.Server.Implementations.Serialization; +using Emby.Server.Implementations.Threading; +using Emby.Server.Implementations.Xml; using Emby.Server.MediaEncoding.Subtitles; using MediaBrowser.MediaEncoding.BdInfo; +using MediaBrowser.Model.Cryptography; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Tasks; +using MediaBrowser.Model.Threading; using StringExtensions = MediaBrowser.Controller.Extensions.StringExtensions; namespace Emby.Server.Implementations @@ -123,8 +134,124 @@ namespace Emby.Server.Implementations /// /// Class CompositionRoot /// - public abstract class ApplicationHost : BaseApplicationHost, IServerApplicationHost, IDependencyContainer + public abstract class ApplicationHost : IServerApplicationHost, IDependencyContainer { + /// + /// Gets a value indicating whether this instance can self restart. + /// + /// true if this instance can self restart; otherwise, false. + public abstract bool CanSelfRestart { get; } + + /// + /// Gets or sets a value indicating whether this instance can self update. + /// + /// true if this instance can self update; otherwise, false. + public virtual bool CanSelfUpdate + { + get + { + return false; + } + } + + /// + /// Occurs when [has pending restart changed]. + /// + public event EventHandler HasPendingRestartChanged; + + /// + /// Occurs when [application updated]. + /// + public event EventHandler> ApplicationUpdated; + + /// + /// Gets or sets a value indicating whether this instance has changes that require the entire application to restart. + /// + /// true if this instance has pending application restart; otherwise, false. + public bool HasPendingRestart { get; private set; } + + /// + /// Gets or sets the logger. + /// + /// The logger. + protected ILogger Logger { get; set; } + + /// + /// Gets or sets the plugins. + /// + /// The plugins. + public IPlugin[] Plugins { get; protected set; } + + /// + /// Gets or sets the log manager. + /// + /// The log manager. + public ILogManager LogManager { get; protected set; } + + /// + /// Gets the application paths. + /// + /// The application paths. + protected ServerApplicationPaths ApplicationPaths { get; set; } + + /// + /// Gets assemblies that failed to load + /// + /// The failed assemblies. + public List FailedAssemblies { get; protected set; } + + /// + /// Gets all concrete types. + /// + /// All concrete types. + public Type[] AllConcreteTypes { get; protected set; } + + /// + /// The disposable parts + /// + protected readonly List DisposableParts = new List(); + + /// + /// Gets a value indicating whether this instance is first run. + /// + /// true if this instance is first run; otherwise, false. + public bool IsFirstRun { get; private set; } + + /// + /// Gets the configuration manager. + /// + /// The configuration manager. + protected IConfigurationManager ConfigurationManager { get; set; } + + public IFileSystem FileSystemManager { get; set; } + + protected IEnvironmentInfo EnvironmentInfo { get; set; } + + public PackageVersionClass SystemUpdateLevel + { + get + { + +#if BETA + return PackageVersionClass.Beta; +#endif + return PackageVersionClass.Release; + } + } + + public virtual string OperatingSystemDisplayName + { + get { return EnvironmentInfo.OperatingSystemName; } + } + + /// + /// The container + /// + protected readonly SimpleInjector.Container Container = new SimpleInjector.Container(); + + protected ISystemEvents SystemEvents { get; set; } + protected IMemoryStreamFactory MemoryStreamFactory { get; set; } + /// /// Gets the server configuration manager. /// @@ -138,7 +265,7 @@ namespace Emby.Server.Implementations /// Gets the configuration manager. /// /// IConfigurationManager. - protected override IConfigurationManager GetConfigurationManager() + protected IConfigurationManager GetConfigurationManager() { return new ServerConfigurationManager(ApplicationPaths, LogManager, XmlSerializer, FileSystemManager); } @@ -242,8 +369,17 @@ namespace Emby.Server.Implementations internal IPowerManagement PowerManagement { get; private set; } internal IImageEncoder ImageEncoder { get; private set; } - private readonly Action _certificateGenerator; - private readonly Func _defaultUserNameFactory; + protected IProcessFactory ProcessFactory { get; private set; } + protected ITimerFactory TimerFactory { get; private set; } + protected ICryptoProvider CryptographyProvider = new CryptographyProvider(); + protected readonly IXmlSerializer XmlSerializer; + + protected ISocketFactory SocketFactory { get; private set; } + protected ITaskManager TaskManager { get; private set; } + public IHttpClient HttpClient { get; private set; } + protected INetworkManager NetworkManager { get; set; } + public IJsonSerializer JsonSerializer { get; private set; } + protected IIsoManager IsoManager { get; private set; } /// /// Initializes a new instance of the class. @@ -257,22 +393,31 @@ namespace Emby.Server.Implementations IEnvironmentInfo environmentInfo, IImageEncoder imageEncoder, ISystemEvents systemEvents, - IMemoryStreamFactory memoryStreamFactory, - INetworkManager networkManager, - Action certificateGenerator, - Func defaultUsernameFactory) - : base(applicationPaths, - logManager, - fileSystem, - environmentInfo, - systemEvents, - memoryStreamFactory, - networkManager) + INetworkManager networkManager) { + // hack alert, until common can target .net core + BaseExtensions.CryptographyProvider = CryptographyProvider; + + XmlSerializer = new MyXmlSerializer(fileSystem, logManager.GetLogger("XmlSerializer")); + + NetworkManager = networkManager; + EnvironmentInfo = environmentInfo; + SystemEvents = systemEvents; + MemoryStreamFactory = new MemoryStreamProvider(); + + FailedAssemblies = new List(); + + ApplicationPaths = applicationPaths; + LogManager = logManager; + FileSystemManager = fileSystem; + + ConfigurationManager = GetConfigurationManager(); + + // Initialize this early in case the -v command line option is used + Logger = LogManager.GetLogger("App"); + StartupOptions = options; - _certificateGenerator = certificateGenerator; _releaseAssetFilename = releaseAssetFilename; - _defaultUserNameFactory = defaultUsernameFactory; PowerManagement = powerManagement; ImageEncoder = imageEncoder; @@ -292,7 +437,7 @@ namespace Emby.Server.Implementations /// Gets the current application version /// /// The application version. - public override Version ApplicationVersion + public Version ApplicationVersion { get { @@ -308,11 +453,25 @@ namespace Emby.Server.Implementations } } + private DeviceId _deviceId; + public string SystemId + { + get + { + if (_deviceId == null) + { + _deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId"), FileSystemManager); + } + + return _deviceId.Value; + } + } + /// /// Gets the name. /// /// The name. - public override string Name + public string Name { get { @@ -341,6 +500,159 @@ namespace Emby.Server.Implementations } } + /// + /// Creates an instance of type and resolves all constructor dependancies + /// + /// The type. + /// System.Object. + public object CreateInstance(Type type) + { + try + { + return Container.GetInstance(type); + } + catch (Exception ex) + { + Logger.ErrorException("Error creating {0}", ex, type.FullName); + + throw; + } + } + + /// + /// Creates the instance safe. + /// + /// The type. + /// System.Object. + 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; + } + } + + /// + /// Registers the specified obj. + /// + /// + /// The obj. + /// if set to true [manage lifetime]. + protected void RegisterSingleInstance(T obj, bool manageLifetime = true) + where T : class + { + Container.RegisterSingleton(obj); + + if (manageLifetime) + { + var disposable = obj as IDisposable; + + if (disposable != null) + { + DisposableParts.Add(disposable); + } + } + } + + /// + /// Registers the single instance. + /// + /// + /// The func. + protected void RegisterSingleInstance(Func func) + where T : class + { + Container.RegisterSingleton(func); + } + + /// + /// Resolves this instance. + /// + /// + /// ``0. + public T Resolve() + { + return (T)Container.GetRegistration(typeof(T), true).GetInstance(); + } + + /// + /// Resolves this instance. + /// + /// + /// ``0. + public T TryResolve() + { + var result = Container.GetRegistration(typeof(T), false); + + if (result == null) + { + return default(T); + } + return (T)result.GetInstance(); + } + + /// + /// Loads the assembly. + /// + /// The file. + /// Assembly. + protected Assembly LoadAssembly(string file) + { + try + { + return Assembly.Load(File.ReadAllBytes(file)); + } + catch (Exception ex) + { + FailedAssemblies.Add(file); + Logger.ErrorException("Error loading assembly {0}", ex, file); + return null; + } + } + + /// + /// Gets the export types. + /// + /// + /// IEnumerable{Type}. + public IEnumerable GetExportTypes() + { + var currentType = typeof(T); + + return AllConcreteTypes.Where(currentType.IsAssignableFrom); + } + + /// + /// Gets the exports. + /// + /// + /// if set to true [manage liftime]. + /// IEnumerable{``0}. + public IEnumerable GetExports(bool manageLiftime = true) + { + var parts = GetExportTypes() + .Select(CreateInstanceSafe) + .Where(i => i != null) + .Cast() + .ToList(); + + if (manageLiftime) + { + lock (DisposableParts) + { + DisposableParts.AddRange(parts.OfType()); + } + } + + return parts; + } + private void SetBaseExceptionMessage() { var builder = GetBaseExceptionMessage(ApplicationPaths); @@ -354,11 +666,13 @@ namespace Emby.Server.Implementations /// /// Runs the startup tasks. /// - public override async Task RunStartupTasks() + public async Task RunStartupTasks() { - await PerformPreInitMigrations().ConfigureAwait(false); + Resolve().AddTasks(GetExports(false)); - await base.RunStartupTasks().ConfigureAwait(false); + ConfigureAutorun(); + + ConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated; await MediaEncoder.Init().ConfigureAwait(false); @@ -375,7 +689,6 @@ namespace Emby.Server.Implementations Logger.Info("Core startup complete"); HttpServer.GlobalResponse = null; - PerformPostInitMigrations(); Logger.Info("Post-init migrations complete"); foreach (var entryPoint in GetExports().ToList()) @@ -398,7 +711,22 @@ namespace Emby.Server.Implementations LogManager.RemoveConsoleOutput(); } - protected override IJsonSerializer CreateJsonSerializer() + /// + /// Configures the autorun. + /// + private void ConfigureAutorun() + { + try + { + ConfigureAutoRunAtStartup(ConfigurationManager.CommonConfiguration.RunAtStartup); + } + catch (Exception ex) + { + Logger.ErrorException("Error configuring autorun", ex); + } + } + + private IJsonSerializer CreateJsonSerializer() { try { @@ -410,48 +738,10 @@ namespace Emby.Server.Implementations // Failing under mono } - var result = new JsonSerializer(FileSystemManager, LogManager.GetLogger("JsonSerializer")); - - ServiceStack.Text.JsConfig.ExcludePropertyNames = new[] { "ProviderIds" }; - ServiceStack.Text.JsConfig.ExcludePropertyNames = new[] { "ProviderIds" }; - ServiceStack.Text.JsConfig.ExcludePropertyNames = new[] { "ProviderIds" }; - ServiceStack.Text.JsConfig.ExcludePropertyNames = new[] { "ProviderIds" }; - ServiceStack.Text.JsConfig.ExcludePropertyNames = new[] { "ProviderIds" }; - ServiceStack.Text.JsConfig