using MediaBrowser.Api; using MediaBrowser.Common; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Constants; using MediaBrowser.Common.Events; using MediaBrowser.Common.Implementations; using MediaBrowser.Common.Implementations.ScheduledTasks; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Common.Updates; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Controller.Updates; using MediaBrowser.IsoMounter; using MediaBrowser.Model.IO; using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.System; using MediaBrowser.Model.Updates; using MediaBrowser.Server.Implementations; using MediaBrowser.Server.Implementations.BdInfo; using MediaBrowser.Server.Implementations.Configuration; using MediaBrowser.Server.Implementations.HttpServer; using MediaBrowser.Server.Implementations.Library; using MediaBrowser.Server.Implementations.ServerManager; using MediaBrowser.Server.Implementations.Udp; using MediaBrowser.Server.Implementations.Updates; using MediaBrowser.Server.Implementations.WebSocket; using MediaBrowser.ServerApplication.Implementations; using MediaBrowser.WebDashboard.Api; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.ServerApplication { /// /// Class CompositionRoot /// public class ApplicationHost : BaseApplicationHost, IServerApplicationHost { /// /// Gets the server kernel. /// /// The server kernel. protected Kernel ServerKernel { get; set; } /// /// Gets the server configuration manager. /// /// The server configuration manager. public IServerConfigurationManager ServerConfigurationManager { get { return (IServerConfigurationManager)ConfigurationManager; } } /// /// Gets the name of the log file prefix. /// /// The name of the log file prefix. protected override string LogFilePrefixName { get { return "Server"; } } /// /// Gets the configuration manager. /// /// IConfigurationManager. protected override IConfigurationManager GetConfigurationManager() { return new ServerConfigurationManager(ApplicationPaths, LogManager, XmlSerializer); } private IInstallationManager InstallationManager { get; set; } private IServerManager ServerManager { get; set; } public override async Task Init() { await base.Init().ConfigureAwait(false); await ServerKernel.Init().ConfigureAwait(false); } /// /// Registers resources that classes will depend on /// protected override async Task RegisterResources() { ServerKernel = new Kernel(this, XmlSerializer, LogManager, ServerConfigurationManager); await base.RegisterResources().ConfigureAwait(false); RegisterSingleInstance(this); RegisterSingleInstance(ApplicationPaths); RegisterSingleInstance(ServerKernel); RegisterSingleInstance(ServerConfigurationManager); RegisterSingleInstance(() => new AlchemyServer(Logger)); RegisterSingleInstance(new UdpServer(Logger), false); RegisterSingleInstance(new PismoIsoManager(Logger)); RegisterSingleInstance(new BdInfoExaminer()); RegisterSingleInstance(new DotNetZipClient()); RegisterSingleInstance(ServerFactory.CreateServer(this, ProtobufSerializer, Logger, "Media Browser", "index.html"), false); ServerManager = new ServerManager(this, NetworkManager, JsonSerializer, Logger, ServerConfigurationManager, ServerKernel); RegisterSingleInstance(ServerManager); var userManager = new UserManager(ServerKernel, Logger, ServerConfigurationManager); RegisterSingleInstance(userManager); RegisterSingleInstance(new LibraryManager(ServerKernel, Logger, TaskManager, userManager, ServerConfigurationManager)); InstallationManager = new InstallationManager(HttpClient, PackageManager, JsonSerializer, Logger, this); RegisterSingleInstance(InstallationManager); } /// /// Finds the parts. /// protected override void FindParts() { base.FindParts(); Resolve().Init(GetExports(false)); Resolve().AddWebSocketListeners(GetExports(false)); Resolve().Start(); Resolve().AddParts(GetExports(), GetExports(), GetExports(), GetExports()); } /// /// Restarts this instance. /// public override void Restart() { App.Instance.Restart(); } /// /// Gets or sets a value indicating whether this instance can self update. /// /// true if this instance can self update; otherwise, false. public override bool CanSelfUpdate { get { return ConfigurationManager.CommonConfiguration.EnableAutoUpdate; } } /// /// Checks for update. /// /// The cancellation token. /// The progress. /// Task{CheckForUpdateResult}. public async override Task CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress progress) { var pkgManager = Resolve(); var availablePackages = await pkgManager.GetAvailablePackages(CancellationToken.None).ConfigureAwait(false); var version = Resolve().GetLatestCompatibleVersion(availablePackages, Constants.MBServerPkgName, ConfigurationManager.CommonConfiguration.SystemUpdateLevel); return version != null ? new CheckForUpdateResult { AvailableVersion = version.version, IsUpdateAvailable = version.version > ApplicationVersion, Package = version } : new CheckForUpdateResult { AvailableVersion = ApplicationVersion, IsUpdateAvailable = false }; } /// /// Gets the composable part assemblies. /// /// IEnumerable{Assembly}. protected override IEnumerable GetComposablePartAssemblies() { // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that // This will prevent the .dll file from getting locked, and allow us to replace it when needed foreach (var pluginAssembly in Directory .EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly) .Select(LoadAssembly).Where(a => a != null)) { yield return pluginAssembly; } // Include composable parts in the Api assembly yield return typeof(ApiService).Assembly; // Include composable parts in the Dashboard assembly yield return typeof(DashboardInfo).Assembly; // Include composable parts in the Model assembly yield return typeof(SystemInfo).Assembly; // Include composable parts in the Common assembly yield return typeof(IApplicationHost).Assembly; // Include composable parts in the Controller assembly yield return typeof(Kernel).Assembly; // Common implementations yield return typeof(TaskManager).Assembly; // Server implementations yield return typeof(ServerApplicationPaths).Assembly; // Include composable parts in the running assembly yield return GetType().Assembly; } /// /// Gets the system status. /// /// SystemInfo. public virtual SystemInfo GetSystemInfo() { return new SystemInfo { HasPendingRestart = HasPendingRestart, Version = ApplicationVersion.ToString(), IsNetworkDeployed = CanSelfUpdate, WebSocketPortNumber = ServerManager.WebSocketPortNumber, SupportsNativeWebSocket = ServerManager.SupportsNativeWebSocket, FailedPluginAssemblies = FailedAssemblies.ToArray(), InProgressInstallations = InstallationManager.CurrentInstallations.Select(i => i.Item1).ToArray(), CompletedInstallations = InstallationManager.CompletedInstallations.ToArray() }; } /// /// Shuts down. /// public override void Shutdown() { App.Instance.Dispatcher.Invoke(App.Instance.Shutdown); } } }