using MediaBrowser.Common.Kernel; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.MediaInfo; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Updates; using MediaBrowser.Controller.Weather; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.System; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Controller { /// /// Class Kernel /// public class Kernel : BaseKernel { /// /// Gets the instance. /// /// The instance. public static Kernel Instance { get; private set; } /// /// Gets the image manager. /// /// The image manager. public ImageManager ImageManager { get; private set; } /// /// Gets the FFMPEG controller. /// /// The FFMPEG controller. public FFMpegManager FFMpegManager { get; private set; } /// /// Gets the installation manager. /// /// The installation manager. public InstallationManager InstallationManager { get; set; } /// /// Gets or sets the file system manager. /// /// The file system manager. public FileSystemManager FileSystemManager { get; private set; } /// /// Gets the provider manager. /// /// The provider manager. public ProviderManager ProviderManager { get; private set; } /// /// Gets the kernel context. /// /// The kernel context. public override KernelContext KernelContext { get { return KernelContext.Server; } } /// /// Gets the list of Localized string files /// /// The string files. public IEnumerable StringFiles { get; private set; } /// /// Gets the list of plugin configuration pages /// /// The configuration pages. public IEnumerable PluginConfigurationPages { get; private set; } /// /// Gets the list of currently registered weather prvoiders /// /// The weather providers. public IEnumerable WeatherProviders { get; private set; } /// /// Gets the list of currently registered metadata prvoiders /// /// The metadata providers enumerable. public BaseMetadataProvider[] MetadataProviders { get; private set; } /// /// Gets the list of currently registered image processors /// Image processors are specialized metadata providers that run after the normal ones /// /// The image enhancers. public IEnumerable ImageEnhancers { get; private set; } /// /// Gets the list of available user repositories /// /// The user repositories. private IEnumerable UserRepositories { get; set; } /// /// Gets the active user repository /// /// The user repository. public IUserRepository UserRepository { get; private set; } /// /// Gets the active user repository /// /// The display preferences repository. public IDisplayPreferencesRepository DisplayPreferencesRepository { get; private set; } /// /// Gets the list of available item repositories /// /// The item repositories. private IEnumerable ItemRepositories { get; set; } /// /// Gets the active item repository /// /// The item repository. public IItemRepository ItemRepository { get; private set; } /// /// Gets the list of available DisplayPreferencesRepositories /// /// The display preferences repositories. private IEnumerable DisplayPreferencesRepositories { get; set; } /// /// Gets the list of available item repositories /// /// The user data repositories. private IEnumerable UserDataRepositories { get; set; } /// /// Gets the active user data repository /// /// The user data repository. public IUserDataRepository UserDataRepository { get; private set; } /// /// Gets the UDP server port number. /// /// The UDP server port number. public override int UdpServerPortNumber { get { return 7359; } } /// /// Creates a kernel based on a Data path, which is akin to our current programdata path /// /// The app host. /// The app paths. /// The XML serializer. /// The logger. /// isoManager public Kernel(IApplicationHost appHost, IServerApplicationPaths appPaths, IXmlSerializer xmlSerializer, ILogger logger) : base(appHost, appPaths, xmlSerializer, logger) { Instance = this; // For now there's no real way to inject this properly BaseItem.Logger = logger; Ratings.Logger = logger; LocalizedStrings.Logger = logger; } /// /// Composes the parts with ioc container. /// protected void FindParts() { // For now there's no real way to inject this properly BaseItem.LibraryManager = ApplicationHost.Resolve(); User.UserManager = ApplicationHost.Resolve(); FFMpegManager = (FFMpegManager)ApplicationHost.CreateInstance(typeof(FFMpegManager)); ImageManager = (ImageManager)ApplicationHost.CreateInstance(typeof(ImageManager)); ProviderManager = (ProviderManager)ApplicationHost.CreateInstance(typeof(ProviderManager)); SecurityManager = (PluginSecurityManager)ApplicationHost.CreateInstance(typeof(PluginSecurityManager)); UserDataRepositories = ApplicationHost.GetExports(); UserRepositories = ApplicationHost.GetExports(); DisplayPreferencesRepositories = ApplicationHost.GetExports(); ItemRepositories = ApplicationHost.GetExports(); WeatherProviders = ApplicationHost.GetExports(); PluginConfigurationPages = ApplicationHost.GetExports(); ImageEnhancers = ApplicationHost.GetExports().OrderBy(e => e.Priority).ToArray(); StringFiles = ApplicationHost.GetExports(); MetadataProviders = ApplicationHost.GetExports().OrderBy(e => e.Priority).ToArray(); } /// /// Performs initializations that can be reloaded at anytime /// /// Task. protected override async void ReloadInternal() { base.ReloadInternal(); FindParts(); await LoadRepositories().ConfigureAwait(false); ReloadResourcePools(); await ApplicationHost.Resolve().RefreshUsersMetadata(CancellationToken.None).ConfigureAwait(false); foreach (var entryPoint in ApplicationHost.GetExports()) { entryPoint.Run(); } ReloadFileSystemManager(); } /// /// Releases unmanaged and - optionally - managed resources. /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected override void Dispose(bool dispose) { if (dispose) { DisposeResourcePools(); DisposeFileSystemManager(); } base.Dispose(dispose); } /// /// Disposes the resource pools. /// private void DisposeResourcePools() { if (ResourcePools != null) { ResourcePools.Dispose(); ResourcePools = null; } } /// /// Reloads the resource pools. /// private void ReloadResourcePools() { DisposeResourcePools(); ResourcePools = new ResourcePool(); } /// /// Called when [composable parts loaded]. /// /// Task. protected Task LoadRepositories() { // Get the current item repository ItemRepository = GetRepository(ItemRepositories, Configuration.ItemRepository); var itemRepoTask = ItemRepository.Initialize(); // Get the current user repository UserRepository = GetRepository(UserRepositories, Configuration.UserRepository); var userRepoTask = UserRepository.Initialize(); // Get the current item repository UserDataRepository = GetRepository(UserDataRepositories, Configuration.UserDataRepository); var userDataRepoTask = UserDataRepository.Initialize(); // Get the current display preferences repository DisplayPreferencesRepository = GetRepository(DisplayPreferencesRepositories, Configuration.DisplayPreferencesRepository); var displayPreferencesRepoTask = DisplayPreferencesRepository.Initialize(); return Task.WhenAll(itemRepoTask, userRepoTask, userDataRepoTask, displayPreferencesRepoTask); } /// /// Gets a repository by name from a list, and returns the default if not found /// /// /// The repositories. /// The name. /// ``0. private T GetRepository(IEnumerable repositories, string name) where T : class, IRepository { var enumerable = repositories as T[] ?? repositories.ToArray(); return enumerable.FirstOrDefault(r => string.Equals(r.Name, name, StringComparison.OrdinalIgnoreCase)) ?? enumerable.FirstOrDefault(); } /// /// Disposes the file system manager. /// private void DisposeFileSystemManager() { if (FileSystemManager != null) { FileSystemManager.Dispose(); FileSystemManager = null; } } /// /// Reloads the file system manager. /// private void ReloadFileSystemManager() { DisposeFileSystemManager(); FileSystemManager = new FileSystemManager(this, Logger, ApplicationHost.Resolve(), ApplicationHost.Resolve()); FileSystemManager.StartWatchers(); } /// /// Completely overwrites the current configuration with a new copy /// /// The config. public void UpdateConfiguration(ServerConfiguration config) { Configuration = config; SaveConfiguration(); // Validate currently executing providers, in the background Task.Run(() => { ProviderManager.ValidateCurrentlyRunningProviders(); }); } /// /// Gets the system info. /// /// SystemInfo. public override SystemInfo GetSystemInfo() { var info = base.GetSystemInfo(); if (InstallationManager != null) { info.InProgressInstallations = InstallationManager.CurrentInstallations.Select(i => i.Item1).ToArray(); info.CompletedInstallations = InstallationManager.CompletedInstallations.ToArray(); } return info; } } }