diff options
| author | LukePulverenti <luke.pulverenti@gmail.com> | 2013-02-20 20:33:05 -0500 |
|---|---|---|
| committer | LukePulverenti <luke.pulverenti@gmail.com> | 2013-02-20 20:33:05 -0500 |
| commit | 767cdc1f6f6a63ce997fc9476911e2c361f9d402 (patch) | |
| tree | 49add55976f895441167c66cfa95e5c7688d18ce /MediaBrowser.Controller/Kernel.cs | |
| parent | 845554722efaed872948a9e0f7202e3ef52f1b6e (diff) | |
Pushing missing changes
Diffstat (limited to 'MediaBrowser.Controller/Kernel.cs')
| -rw-r--r-- | MediaBrowser.Controller/Kernel.cs | 985 |
1 files changed, 599 insertions, 386 deletions
diff --git a/MediaBrowser.Controller/Kernel.cs b/MediaBrowser.Controller/Kernel.cs index 2430260dd..aca7c4bd2 100644 --- a/MediaBrowser.Controller/Kernel.cs +++ b/MediaBrowser.Controller/Kernel.cs @@ -1,386 +1,599 @@ -using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Controller.Resolvers;
-using MediaBrowser.Controller.Weather;
-using MediaBrowser.Model.Authentication;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Progress;
-using MediaBrowser.Common.Extensions;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.Composition;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Security.Cryptography;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Controller
-{
- public class Kernel : BaseKernel<ServerConfiguration, ServerApplicationPaths>
- {
- #region Events
- /// <summary>
- /// Fires whenever any validation routine adds or removes items. The added and removed items are properties of the args.
- /// *** Will fire asynchronously. ***
- /// </summary>
- public event EventHandler<ChildrenChangedEventArgs> LibraryChanged;
- public void OnLibraryChanged(ChildrenChangedEventArgs args)
- {
- if (LibraryChanged != null)
- {
- Task.Run(() => LibraryChanged(this, args));
- }
- }
-
- #endregion
- public static Kernel Instance { get; private set; }
-
- public ItemController ItemController { get; private set; }
-
- public IEnumerable<User> Users { get; private set; }
- public Folder RootFolder { get; private set; }
-
- private DirectoryWatchers DirectoryWatchers { get; set; }
-
- private string MediaRootFolderPath
- {
- get
- {
- return ApplicationPaths.RootFolderPath;
- }
- }
-
- public override KernelContext KernelContext
- {
- get { return KernelContext.Server; }
- }
-
- /// <summary>
- /// Gets the list of currently registered weather prvoiders
- /// </summary>
- [ImportMany(typeof(BaseWeatherProvider))]
- public IEnumerable<BaseWeatherProvider> WeatherProviders { get; private set; }
-
- /// <summary>
- /// Gets the list of currently registered metadata prvoiders
- /// </summary>
- [ImportMany(typeof(BaseMetadataProvider))]
- private IEnumerable<BaseMetadataProvider> MetadataProvidersEnumerable { get; set; }
-
- /// <summary>
- /// Once MEF has loaded the resolvers, sort them by priority and store them in this array
- /// Given the sheer number of times they'll be iterated over it'll be faster to loop through an array
- /// </summary>
- private BaseMetadataProvider[] MetadataProviders { get; set; }
-
- /// <summary>
- /// Gets the list of currently registered entity resolvers
- /// </summary>
- [ImportMany(typeof(IBaseItemResolver))]
- private IEnumerable<IBaseItemResolver> EntityResolversEnumerable { get; set; }
-
- /// <summary>
- /// Once MEF has loaded the resolvers, sort them by priority and store them in this array
- /// Given the sheer number of times they'll be iterated over it'll be faster to loop through an array
- /// </summary>
- internal IBaseItemResolver[] EntityResolvers { get; private set; }
-
- /// <summary>
- /// Creates a kernel based on a Data path, which is akin to our current programdata path
- /// </summary>
- public Kernel()
- : base()
- {
- Instance = this;
- }
-
- /// <summary>
- /// Performs initializations that only occur once
- /// </summary>
- protected override void InitializeInternal(IProgress<TaskProgress> progress)
- {
- base.InitializeInternal(progress);
-
- ItemController = new ItemController();
- DirectoryWatchers = new DirectoryWatchers();
-
-
- ExtractFFMpeg();
- }
-
- /// <summary>
- /// Performs initializations that can be reloaded at anytime
- /// </summary>
- protected override async Task ReloadInternal(IProgress<TaskProgress> progress)
- {
- await base.ReloadInternal(progress).ConfigureAwait(false);
-
- ReportProgress(progress, "Loading Users");
- ReloadUsers();
-
- ReportProgress(progress, "Loading Media Library");
-
- await ReloadRoot(allowInternetProviders: false).ConfigureAwait(false);
-
- }
-
- /// <summary>
- /// Completely disposes the Kernel
- /// </summary>
- public override void Dispose()
- {
- base.Dispose();
-
- DirectoryWatchers.Stop();
-
- }
-
- protected override void OnComposablePartsLoaded()
- {
- // The base class will start up all the plugins
- base.OnComposablePartsLoaded();
-
- // Sort the resolvers by priority
- EntityResolvers = EntityResolversEnumerable.OrderBy(e => e.Priority).ToArray();
-
- // Sort the providers by priority
- MetadataProviders = MetadataProvidersEnumerable.OrderBy(e => e.Priority).ToArray();
- }
-
- public BaseItem ResolveItem(ItemResolveEventArgs args)
- {
- // Try first priority resolvers
- for (int i = 0; i < EntityResolvers.Length; i++)
- {
- var item = EntityResolvers[i].ResolvePath(args);
-
- if (item != null)
- {
- item.ResolveArgs = args;
- return item;
- }
- }
-
- return null;
- }
-
- private void ReloadUsers()
- {
- Users = GetAllUsers();
- }
-
- /// <summary>
- /// Reloads the root media folder
- /// </summary>
- public async Task ReloadRoot(bool allowInternetProviders = true)
- {
- if (!Directory.Exists(MediaRootFolderPath))
- {
- Directory.CreateDirectory(MediaRootFolderPath);
- }
-
- DirectoryWatchers.Stop();
-
- RootFolder = await ItemController.GetItem(MediaRootFolderPath, allowInternetProviders: allowInternetProviders).ConfigureAwait(false) as Folder;
- RootFolder.ChildrenChanged += RootFolder_ChildrenChanged;
-
- DirectoryWatchers.Start();
- }
-
- void RootFolder_ChildrenChanged(object sender, ChildrenChangedEventArgs e)
- {
- Logger.LogDebugInfo("Root Folder Children Changed. Added: " + e.ItemsAdded.Count + " Removed: " + e.ItemsRemoved.Count());
- //re-start the directory watchers
- DirectoryWatchers.Stop();
- DirectoryWatchers.Start();
- //Task.Delay(30000); //let's wait and see if more data gets filled in...
- var allChildren = RootFolder.RecursiveChildren;
- Logger.LogDebugInfo(string.Format("Loading complete. Movies: {0} Episodes: {1} Folders: {2}", allChildren.OfType<Entities.Movies.Movie>().Count(), allChildren.OfType<Entities.TV.Episode>().Count(), allChildren.Where(i => i is Folder && !(i is Series || i is Season)).Count()));
- //foreach (var child in allChildren)
- //{
- // Logger.LogDebugInfo("(" + child.GetType().Name + ") " + child.Name + " (" + child.Path + ")");
- //}
- }
-
- /// <summary>
- /// Gets the default user to use when EnableUserProfiles is false
- /// </summary>
- public User GetDefaultUser()
- {
- User user = Users.FirstOrDefault();
-
- return user;
- }
-
- /// <summary>
- /// Persists a User
- /// </summary>
- public void SaveUser(User user)
- {
-
- }
-
- /// <summary>
- /// Authenticates a User and returns a result indicating whether or not it succeeded
- /// </summary>
- public AuthenticationResult AuthenticateUser(User user, string password)
- {
- var result = new AuthenticationResult();
-
- // When EnableUserProfiles is false, only the default User can login
- if (!Configuration.EnableUserProfiles)
- {
- result.Success = user.Id == GetDefaultUser().Id;
- }
- else if (string.IsNullOrEmpty(user.Password))
- {
- result.Success = true;
- }
- else
- {
- password = password ?? string.Empty;
- result.Success = password.GetMD5().ToString().Equals(user.Password);
- }
-
- // Update LastActivityDate and LastLoginDate, then save
- if (result.Success)
- {
- user.LastActivityDate = user.LastLoginDate = DateTime.UtcNow;
- SaveUser(user);
- }
-
- return result;
- }
-
- /// <summary>
- /// Finds a library item by Id
- /// </summary>
- public BaseItem GetItemById(Guid id)
- {
- if (id == Guid.Empty)
- {
- return RootFolder;
- }
-
- return RootFolder.FindItemById(id);
- }
-
- /// <summary>
- /// Gets all users within the system
- /// </summary>
- private IEnumerable<User> GetAllUsers()
- {
- var list = new List<User>();
-
- // Return a dummy user for now since all calls to get items requre a userId
- var user = new User { };
-
- user.Name = "Default User";
- user.Id = Guid.Parse("5d1cf7fce25943b790d140095457a42b");
- user.PrimaryImagePath = "D:\\Video\\TV\\Archer (2009)\\backdrop.jpg";
- list.Add(user);
-
- user = new User { };
- user.Name = "Abobader";
- user.Id = Guid.NewGuid();
- user.LastLoginDate = DateTime.UtcNow.AddDays(-1);
- user.LastActivityDate = DateTime.UtcNow.AddHours(-3);
- user.Password = ("1234").GetMD5().ToString();
- list.Add(user);
-
- user = new User { };
- user.Name = "Scottisafool";
- user.Id = Guid.NewGuid();
- list.Add(user);
-
- user = new User { };
- user.Name = "Redshirt";
- user.Id = Guid.NewGuid();
- list.Add(user);
-
- /*user = new User();
- user.Name = "Test User 4";
- user.Id = Guid.NewGuid();
- list.Add(user);
-
- user = new User();
- user.Name = "Test User 5";
- user.Id = Guid.NewGuid();
- list.Add(user);
-
- user = new User();
- user.Name = "Test User 6";
- user.Id = Guid.NewGuid();
- list.Add(user);*/
-
- return list;
- }
-
- /// <summary>
- /// Runs all metadata providers for an entity
- /// </summary>
- internal async Task ExecuteMetadataProviders(BaseEntity item, bool allowInternetProviders = true)
- {
- // Run them sequentially in order of priority
- for (int i = 0; i < MetadataProviders.Length; i++)
- {
- var provider = MetadataProviders[i];
-
- // Skip if internet providers are currently disabled
- if (provider.RequiresInternet && (!Configuration.EnableInternetProviders || !allowInternetProviders))
- {
- continue;
- }
-
- // Skip if the provider doesn't support the current item
- if (!provider.Supports(item))
- {
- continue;
- }
-
- try
- {
- await provider.FetchIfNeededAsync(item).ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- Logger.LogException(ex);
- }
- }
- }
-
- private void ExtractFFMpeg()
- {
- ExtractFFMpeg(ApplicationPaths.FFMpegPath);
- ExtractFFMpeg(ApplicationPaths.FFProbePath);
- }
-
- /// <summary>
- /// Run these during Init.
- /// Can't run do this on-demand because there will be multiple workers accessing them at once and we'd have to lock them
- /// </summary>
- private void ExtractFFMpeg(string exe)
- {
- if (File.Exists(exe))
- {
- File.Delete(exe);
- }
-
- // Extract exe
- using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MediaBrowser.Controller.FFMpeg." + Path.GetFileName(exe)))
- {
- using (var fileStream = new FileStream(exe, FileMode.Create))
- {
- stream.CopyTo(fileStream);
- }
- }
- }
- }
-}
+using MediaBrowser.Common.Kernel; +using MediaBrowser.Common.Plugins; +using MediaBrowser.Controller.Drawing; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.IO; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.MediaInfo; +using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.Persistence.SQLite; +using MediaBrowser.Controller.Playback; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Controller.Resolvers; +using MediaBrowser.Controller.ScheduledTasks; +using MediaBrowser.Controller.Updates; +using MediaBrowser.Controller.Weather; +using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.System; +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller +{ + /// <summary> + /// Class Kernel + /// </summary> + public class Kernel : BaseKernel<ServerConfiguration, ServerApplicationPaths> + { + /// <summary> + /// The MB admin URL + /// </summary> + public const string MBAdminUrl = "http://mb3admin.com/admin/"; + + /// <summary> + /// Gets the instance. + /// </summary> + /// <value>The instance.</value> + public static Kernel Instance { get; private set; } + + /// <summary> + /// Gets the library manager. + /// </summary> + /// <value>The library manager.</value> + public LibraryManager LibraryManager { get; private set; } + + /// <summary> + /// Gets the image manager. + /// </summary> + /// <value>The image manager.</value> + public ImageManager ImageManager { get; private set; } + + /// <summary> + /// Gets the user manager. + /// </summary> + /// <value>The user manager.</value> + public UserManager UserManager { get; private set; } + + /// <summary> + /// Gets the FFMPEG controller. + /// </summary> + /// <value>The FFMPEG controller.</value> + public FFMpegManager FFMpegManager { get; private set; } + + /// <summary> + /// Gets the installation manager. + /// </summary> + /// <value>The installation manager.</value> + public InstallationManager InstallationManager { get; private set; } + + /// <summary> + /// Gets or sets the file system manager. + /// </summary> + /// <value>The file system manager.</value> + public FileSystemManager FileSystemManager { get; private set; } + + /// <summary> + /// Gets the provider manager. + /// </summary> + /// <value>The provider manager.</value> + public ProviderManager ProviderManager { get; private set; } + + /// <summary> + /// Gets the user data manager. + /// </summary> + /// <value>The user data manager.</value> + public UserDataManager UserDataManager { get; private set; } + + /// <summary> + /// Gets the plug-in security manager. + /// </summary> + /// <value>The plug-in security manager.</value> + public PluginSecurityManager PluginSecurityManager { get; private set; } + + /// <summary> + /// The _users + /// </summary> + private IEnumerable<User> _users; + /// <summary> + /// The _user lock + /// </summary> + private object _usersSyncLock = new object(); + /// <summary> + /// The _users initialized + /// </summary> + private bool _usersInitialized; + /// <summary> + /// Gets the users. + /// </summary> + /// <value>The users.</value> + public IEnumerable<User> Users + { + get + { + // Call ToList to exhaust the stream because we'll be iterating over this multiple times + LazyInitializer.EnsureInitialized(ref _users, ref _usersInitialized, ref _usersSyncLock, UserManager.LoadUsers); + return _users; + } + internal set + { + _users = value; + + if (value == null) + { + _usersInitialized = false; + } + } + } + + /// <summary> + /// The _root folder + /// </summary> + private AggregateFolder _rootFolder; + /// <summary> + /// The _root folder sync lock + /// </summary> + private object _rootFolderSyncLock = new object(); + /// <summary> + /// The _root folder initialized + /// </summary> + private bool _rootFolderInitialized; + /// <summary> + /// Gets the root folder. + /// </summary> + /// <value>The root folder.</value> + public AggregateFolder RootFolder + { + get + { + LazyInitializer.EnsureInitialized(ref _rootFolder, ref _rootFolderInitialized, ref _rootFolderSyncLock, LibraryManager.CreateRootFolder); + return _rootFolder; + } + private set + { + _rootFolder = value; + + if (value == null) + { + _rootFolderInitialized = false; + } + } + } + + /// <summary> + /// Gets the kernel context. + /// </summary> + /// <value>The kernel context.</value> + public override KernelContext KernelContext + { + get { return KernelContext.Server; } + } + + /// <summary> + /// Gets the list of plugin configuration pages + /// </summary> + /// <value>The configuration pages.</value> + [ImportMany(typeof(BaseConfigurationPage))] + public IEnumerable<BaseConfigurationPage> PluginConfigurationPages { get; private set; } + + /// <summary> + /// Gets the intro providers. + /// </summary> + /// <value>The intro providers.</value> + [ImportMany(typeof(BaseIntroProvider))] + public IEnumerable<BaseIntroProvider> IntroProviders { get; private set; } + + /// <summary> + /// Gets the list of currently registered weather prvoiders + /// </summary> + /// <value>The weather providers.</value> + [ImportMany(typeof(BaseWeatherProvider))] + public IEnumerable<BaseWeatherProvider> WeatherProviders { get; private set; } + + /// <summary> + /// Gets the list of currently registered metadata prvoiders + /// </summary> + /// <value>The metadata providers enumerable.</value> + [ImportMany(typeof(BaseMetadataProvider))] + public BaseMetadataProvider[] MetadataProviders { get; private set; } + + /// <summary> + /// Gets the list of currently registered image processors + /// Image processors are specialized metadata providers that run after the normal ones + /// </summary> + /// <value>The image enhancers.</value> + [ImportMany(typeof(BaseImageEnhancer))] + public BaseImageEnhancer[] ImageEnhancers { get; private set; } + + /// <summary> + /// Gets the list of currently registered entity resolvers + /// </summary> + /// <value>The entity resolvers enumerable.</value> + [ImportMany(typeof(IBaseItemResolver))] + internal IBaseItemResolver[] EntityResolvers { get; private set; } + + /// <summary> + /// Gets the list of BasePluginFolders added by plugins + /// </summary> + /// <value>The plugin folders.</value> + [ImportMany(typeof(BasePluginFolder))] + internal IEnumerable<BasePluginFolder> PluginFolders { get; private set; } + + /// <summary> + /// Gets the list of available user repositories + /// </summary> + /// <value>The user repositories.</value> + [ImportMany(typeof(IUserRepository))] + private IEnumerable<IUserRepository> UserRepositories { get; set; } + + /// <summary> + /// Gets the active user repository + /// </summary> + /// <value>The user repository.</value> + public IUserRepository UserRepository { get; private set; } + + /// <summary> + /// Gets the active user repository + /// </summary> + /// <value>The display preferences repository.</value> + public IDisplayPreferencesRepository DisplayPreferencesRepository { get; private set; } + + /// <summary> + /// Gets the list of available item repositories + /// </summary> + /// <value>The item repositories.</value> + [ImportMany(typeof(IItemRepository))] + private IEnumerable<IItemRepository> ItemRepositories { get; set; } + + /// <summary> + /// Gets the active item repository + /// </summary> + /// <value>The item repository.</value> + public IItemRepository ItemRepository { get; private set; } + + /// <summary> + /// Gets the list of available item repositories + /// </summary> + /// <value>The user data repositories.</value> + [ImportMany(typeof(IUserDataRepository))] + private IEnumerable<IUserDataRepository> UserDataRepositories { get; set; } + + /// <summary> + /// Gets the list of available DisplayPreferencesRepositories + /// </summary> + /// <value>The display preferences repositories.</value> + [ImportMany(typeof(IDisplayPreferencesRepository))] + private IEnumerable<IDisplayPreferencesRepository> DisplayPreferencesRepositories { get; set; } + + /// <summary> + /// Gets the list of entity resolution ignore rules + /// </summary> + /// <value>The entity resolution ignore rules.</value> + [ImportMany(typeof(BaseResolutionIgnoreRule))] + internal IEnumerable<BaseResolutionIgnoreRule> EntityResolutionIgnoreRules { get; private set; } + + /// <summary> + /// Gets the active user data repository + /// </summary> + /// <value>The user data repository.</value> + public IUserDataRepository UserDataRepository { get; private set; } + + /// <summary> + /// Limits simultaneous access to various resources + /// </summary> + /// <value>The resource pools.</value> + public ResourcePool ResourcePools { get; set; } + + /// <summary> + /// Gets the UDP server port number. + /// </summary> + /// <value>The UDP server port number.</value> + public override int UdpServerPortNumber + { + get { return 7359; } + } + + /// <summary> + /// Creates a kernel based on a Data path, which is akin to our current programdata path + /// </summary> + public Kernel() + : base() + { + Instance = this; + } + + /// <summary> + /// Performs initializations that can be reloaded at anytime + /// </summary> + /// <returns>Task.</returns> + protected override async Task ReloadInternal() + { + Logger.Info("Extracting tools"); + + // Reset these so that they can be lazy loaded again + Users = null; + RootFolder = null; + + ReloadResourcePools(); + InstallationManager = new InstallationManager(this); + LibraryManager = new LibraryManager(this); + UserManager = new UserManager(this); + FFMpegManager = new FFMpegManager(this); + ImageManager = new ImageManager(this); + ProviderManager = new ProviderManager(this); + UserDataManager = new UserDataManager(this); + PluginSecurityManager = new PluginSecurityManager(this); + + await base.ReloadInternal().ConfigureAwait(false); + + ReloadFileSystemManager(); + + await UserManager.RefreshUsersMetadata(CancellationToken.None).ConfigureAwait(false); + } + + /// <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 override void Dispose(bool dispose) + { + if (dispose) + { + DisposeResourcePools(); + + DisposeFileSystemManager(); + } + + base.Dispose(dispose); + } + + /// <summary> + /// Disposes the resource pools. + /// </summary> + private void DisposeResourcePools() + { + if (ResourcePools != null) + { + ResourcePools.Dispose(); + ResourcePools = null; + } + } + + /// <summary> + /// Reloads the resource pools. + /// </summary> + private void ReloadResourcePools() + { + DisposeResourcePools(); + ResourcePools = new ResourcePool(); + } + + /// <summary> + /// Called when [composable parts loaded]. + /// </summary> + /// <returns>Task.</returns> + protected override async Task OnComposablePartsLoaded() + { + // The base class will start up all the plugins + await base.OnComposablePartsLoaded().ConfigureAwait(false); + + // Get the current item repository + ItemRepository = GetRepository(ItemRepositories, Configuration.ItemRepository, SQLiteItemRepository.RepositoryName); + var itemRepoTask = ItemRepository.Initialize(); + + // Get the current user repository + UserRepository = GetRepository(UserRepositories, Configuration.UserRepository, SQLiteUserRepository.RepositoryName); + var userRepoTask = UserRepository.Initialize(); + + // Get the current item repository + UserDataRepository = GetRepository(UserDataRepositories, Configuration.UserDataRepository, SQLiteUserDataRepository.RepositoryName); + var userDataRepoTask = UserDataRepository.Initialize(); + + // Get the current display preferences repository + DisplayPreferencesRepository = GetRepository(DisplayPreferencesRepositories, Configuration.DisplayPreferencesRepository, SQLiteDisplayPreferencesRepository.RepositoryName); + var displayPreferencesRepoTask = DisplayPreferencesRepository.Initialize(); + + // Sort the resolvers by priority + EntityResolvers = EntityResolvers.OrderBy(e => e.Priority).ToArray(); + + // Sort the providers by priority + MetadataProviders = MetadataProviders.OrderBy(e => e.Priority).ToArray(); + + // Sort the image processors by priority + ImageEnhancers = ImageEnhancers.OrderBy(e => e.Priority).ToArray(); + + await Task.WhenAll(itemRepoTask, userRepoTask, userDataRepoTask, displayPreferencesRepoTask).ConfigureAwait(false); + } + + protected override IEnumerable<Assembly> GetComposablePartAssemblies() + { + var runningDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName); + + return base.GetComposablePartAssemblies().Concat(new[] { + + Assembly.Load(File.ReadAllBytes(Path.Combine(runningDirectory, "MediaBrowser.Api.dll"))), + Assembly.Load(File.ReadAllBytes(Path.Combine(runningDirectory, "MediaBrowser.ApiInteraction.Javascript.dll"))), + Assembly.Load(File.ReadAllBytes(Path.Combine(runningDirectory, "MediaBrowser.WebDashboard.dll"))) + }); + } + + /// <summary> + /// Gets a repository by name from a list, and returns the default if not found + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="repositories">The repositories.</param> + /// <param name="name">The name.</param> + /// <param name="defaultName">The default name.</param> + /// <returns>``0.</returns> + private T GetRepository<T>(IEnumerable<T> repositories, string name, string defaultName) + where T : class, IRepository + { + var enumerable = repositories as T[] ?? repositories.ToArray(); + + return enumerable.FirstOrDefault(r => r.Name.Equals(name ?? defaultName, StringComparison.OrdinalIgnoreCase)) ?? + enumerable.First(r => r.Name.Equals(defaultName, StringComparison.OrdinalIgnoreCase)); + } + + /// <summary> + /// Disposes the file system manager. + /// </summary> + private void DisposeFileSystemManager() + { + if (FileSystemManager != null) + { + FileSystemManager.Dispose(); + FileSystemManager = null; + } + } + + /// <summary> + /// Reloads the file system manager. + /// </summary> + private void ReloadFileSystemManager() + { + DisposeFileSystemManager(); + + FileSystemManager = new FileSystemManager(this); + FileSystemManager.StartWatchers(); + } + + /// <summary> + /// Gets a User by Id + /// </summary> + /// <param name="id">The id.</param> + /// <returns>User.</returns> + /// <exception cref="System.ArgumentNullException"></exception> + public User GetUserById(Guid id) + { + if (id == Guid.Empty) + { + throw new ArgumentNullException(); + } + + return Users.FirstOrDefault(u => u.Id == id); + } + + /// <summary> + /// Finds a library item by Id and UserId. + /// </summary> + /// <param name="id">The id.</param> + /// <param name="userId">The user id.</param> + /// <returns>BaseItem.</returns> + /// <exception cref="System.ArgumentNullException">id</exception> + public BaseItem GetItemById(Guid id, Guid userId) + { + if (id == Guid.Empty) + { + throw new ArgumentNullException("id"); + } + + if (userId == Guid.Empty) + { + throw new ArgumentNullException("userId"); + } + + var user = GetUserById(userId); + var userRoot = user.RootFolder; + + return userRoot.FindItemById(id, user); + } + + /// <summary> + /// Gets the item by id. + /// </summary> + /// <param name="id">The id.</param> + /// <returns>BaseItem.</returns> + /// <exception cref="System.ArgumentNullException">id</exception> + public BaseItem GetItemById(Guid id) + { + if (id == Guid.Empty) + { + throw new ArgumentNullException("id"); + } + + return RootFolder.FindItemById(id, null); + } + + /// <summary> + /// Completely overwrites the current configuration with a new copy + /// </summary> + /// <param name="config">The config.</param> + public void UpdateConfiguration(ServerConfiguration config) + { + var oldConfiguration = Configuration; + + var reloadLogger = config.ShowLogWindow != oldConfiguration.ShowLogWindow; + + // Figure out whether or not we should refresh people after the update is finished + var refreshPeopleAfterUpdate = !oldConfiguration.EnableInternetProviders && config.EnableInternetProviders; + + // This is true if internet providers has just been turned on, or if People have just been removed from InternetProviderExcludeTypes + if (!refreshPeopleAfterUpdate) + { + var oldConfigurationFetchesPeopleImages = oldConfiguration.InternetProviderExcludeTypes == null || !oldConfiguration.InternetProviderExcludeTypes.Contains(typeof(Person).Name, StringComparer.OrdinalIgnoreCase); + var newConfigurationFetchesPeopleImages = config.InternetProviderExcludeTypes == null || !config.InternetProviderExcludeTypes.Contains(typeof(Person).Name, StringComparer.OrdinalIgnoreCase); + + refreshPeopleAfterUpdate = newConfigurationFetchesPeopleImages && !oldConfigurationFetchesPeopleImages; + } + + Configuration = config; + SaveConfiguration(); + + if (reloadLogger) + { + ReloadLogger(); + } + + TcpManager.OnApplicationConfigurationChanged(oldConfiguration, config); + + // Validate currently executing providers, in the background + Task.Run(() => + { + ProviderManager.ValidateCurrentlyRunningProviders(); + + // Any number of configuration settings could change the way the library is refreshed, so do that now + TaskManager.CancelIfRunningAndQueue<RefreshMediaLibraryTask>(); + + if (refreshPeopleAfterUpdate) + { + TaskManager.CancelIfRunningAndQueue<PeopleValidationTask>(); + } + }); + } + + /// <summary> + /// Removes the plugin. + /// </summary> + /// <param name="plugin">The plugin.</param> + internal void RemovePlugin(IPlugin plugin) + { + var list = Plugins.ToList(); + list.Remove(plugin); + Plugins = list; + } + + /// <summary> + /// Gets the system info. + /// </summary> + /// <returns>SystemInfo.</returns> + 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; + } + } +} |
