Explorar o código

referenced core plugins, fixed some dashboard issues, extracted library manager

LukePulverenti %!s(int64=12) %!d(string=hai) anos
pai
achega
af7aa597c3
Modificáronse 52 ficheiros con 557 adicións e 337 borrados
  1. 0 1
      BDInfo/BDInfo.csproj
  2. 12 8
      MediaBrowser.Api/EnvironmentService.cs
  3. 12 14
      MediaBrowser.Api/Images/ImageService.cs
  4. 13 23
      MediaBrowser.Api/Library/LibraryService.cs
  5. 9 5
      MediaBrowser.Api/Library/LibraryStructureService.cs
  6. 2 1
      MediaBrowser.Api/MediaBrowser.Api.csproj
  7. 10 2
      MediaBrowser.Api/Playback/BaseStreamingService.cs
  8. 2 1
      MediaBrowser.Api/Playback/Hls/AudioHlsService.cs
  9. 3 3
      MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
  10. 2 2
      MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
  11. 2 2
      MediaBrowser.Api/Playback/Progressive/AudioService.cs
  12. 2 2
      MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
  13. 2 2
      MediaBrowser.Api/Playback/Progressive/VideoService.cs
  14. 5 3
      MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
  15. 4 7
      MediaBrowser.Api/UserLibrary/GenresService.cs
  16. 9 3
      MediaBrowser.Api/UserLibrary/ItemsService.cs
  17. 3 4
      MediaBrowser.Api/UserLibrary/PersonsService.cs
  18. 4 7
      MediaBrowser.Api/UserLibrary/StudiosService.cs
  19. 21 20
      MediaBrowser.Api/UserLibrary/UserLibraryService.cs
  20. 5 8
      MediaBrowser.Api/UserLibrary/YearsService.cs
  21. 19 13
      MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs
  22. 39 5
      MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
  23. 2 1
      MediaBrowser.Controller/Entities/BaseItem.cs
  24. 1 1
      MediaBrowser.Controller/Entities/CollectionFolder.cs
  25. 6 6
      MediaBrowser.Controller/Entities/Folder.cs
  26. 1 1
      MediaBrowser.Controller/Entities/Movies/Movie.cs
  27. 1 1
      MediaBrowser.Controller/Entities/User.cs
  28. 1 1
      MediaBrowser.Controller/Entities/UserRootFolder.cs
  29. 11 8
      MediaBrowser.Controller/IO/DirectoryWatchers.cs
  30. 4 2
      MediaBrowser.Controller/IO/FileSystemManager.cs
  31. 5 91
      MediaBrowser.Controller/Kernel.cs
  32. 18 16
      MediaBrowser.Controller/Library/DtoBuilder.cs
  33. 145 0
      MediaBrowser.Controller/Library/ILibraryManager.cs
  34. 1 1
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  35. 9 5
      MediaBrowser.Controller/ScheduledTasks/PeopleValidationTask.cs
  36. 7 6
      MediaBrowser.Controller/ScheduledTasks/RefreshMediaLibraryTask.cs
  37. 3 2
      MediaBrowser.Server.Implementations/BdInfo/BdInfoExaminer.cs
  38. 98 16
      MediaBrowser.Server.Implementations/Library/LibraryManager.cs
  39. 9 0
      MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
  40. 6 2
      MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs
  41. 7 4
      MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/ImageCleanupTask.cs
  42. 1 0
      MediaBrowser.Server.Implementations/packages.config
  43. 12 14
      MediaBrowser.ServerApplication/ApplicationHost.cs
  44. 6 3
      MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs
  45. 6 3
      MediaBrowser.ServerApplication/MainWindow.xaml.cs
  46. 7 9
      MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
  47. 2 1
      MediaBrowser.WebDashboard/Html/scripts/site.js
  48. 2 1
      MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
  49. 1 1
      Nuget/MediaBrowser.ApiClient.nuspec
  50. 2 2
      Nuget/MediaBrowser.Common.Internal.nuspec
  51. 1 1
      Nuget/MediaBrowser.Common.nuspec
  52. 2 2
      Nuget/MediaBrowser.Server.Core.nuspec

+ 0 - 1
BDInfo/BDInfo.csproj

@@ -35,7 +35,6 @@
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
-    <Compile Include="BdInfoExaminer.cs" />
     <Compile Include="BDInfoSettings.cs" />
     <Compile Include="BDInfoSettings.cs" />
     <Compile Include="BDROM.cs" />
     <Compile Include="BDROM.cs" />
     <Compile Include="LanguageCodes.cs" />
     <Compile Include="LanguageCodes.cs" />

+ 12 - 8
MediaBrowser.Api/EnvironmentService.cs

@@ -97,18 +97,18 @@ namespace MediaBrowser.Api
                 throw new ArgumentNullException("Path");
                 throw new ArgumentNullException("Path");
             }
             }
 
 
-            // Reject invalid input
-            if (!Path.IsPathRooted(path))
+            if (path.StartsWith(NetworkPrefix, StringComparison.OrdinalIgnoreCase) && path.LastIndexOf('\\') == 1)
             {
             {
-                throw new ArgumentException(string.Format("Invalid path: {0}", path));
+                return ToOptimizedResult(GetNetworkShares(path).ToList());
             }
             }
 
 
-            if (path.StartsWith(NetworkPrefix, StringComparison.OrdinalIgnoreCase) && path.LastIndexOf('\\') == 1)
+            // Reject invalid input
+            if (!Path.IsPathRooted(path))
             {
             {
-                return GetNetworkShares(path).ToList();
+                throw new ArgumentException(string.Format("Invalid path: {0}", path));
             }
             }
 
 
-            return GetFileSystemEntries(request).ToList();
+            return ToOptimizedResult(GetFileSystemEntries(request).ToList());
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -118,7 +118,9 @@ namespace MediaBrowser.Api
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         public object Get(GetDrives request)
         public object Get(GetDrives request)
         {
         {
-            return GetDrives().ToList();
+            var result = GetDrives().ToList();
+
+            return ToOptimizedResult(result);
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -128,7 +130,9 @@ namespace MediaBrowser.Api
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         public object Get(GetNetworkComputers request)
         public object Get(GetNetworkComputers request)
         {
         {
-            return GetNetworkComputers().ToList();
+            var result = GetNetworkComputers().ToList();
+
+            return ToOptimizedResult(result);
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 12 - 14
MediaBrowser.Api/Images/ImageService.cs

@@ -141,13 +141,19 @@ namespace MediaBrowser.Api.Images
         /// </summary>
         /// </summary>
         private readonly IUserManager _userManager;
         private readonly IUserManager _userManager;
 
 
+        /// <summary>
+        /// The _library manager
+        /// </summary>
+        private readonly ILibraryManager _libraryManager;
+        
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="ImageService" /> class.
         /// Initializes a new instance of the <see cref="ImageService" /> class.
         /// </summary>
         /// </summary>
         /// <param name="userManager">The user manager.</param>
         /// <param name="userManager">The user manager.</param>
-        public ImageService(IUserManager userManager)
+        public ImageService(IUserManager userManager, ILibraryManager libraryManager)
         {
         {
             _userManager = userManager;
             _userManager = userManager;
+            _libraryManager = libraryManager;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -157,7 +163,7 @@ namespace MediaBrowser.Api.Images
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         public object Get(GetItemImage request)
         public object Get(GetItemImage request)
         {
         {
-            var item = DtoBuilder.GetItemByClientId(request.Id, _userManager);
+            var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager);
 
 
             return GetImage(request, item);
             return GetImage(request, item);
         }
         }
@@ -181,9 +187,7 @@ namespace MediaBrowser.Api.Images
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         public object Get(GetYearImage request)
         public object Get(GetYearImage request)
         {
         {
-            var kernel = (Kernel)Kernel;
-
-            var item = kernel.LibraryManager.GetYear(request.Year).Result;
+            var item = _libraryManager.GetYear(request.Year).Result;
 
 
             return GetImage(request, item);
             return GetImage(request, item);
         }
         }
@@ -195,9 +199,7 @@ namespace MediaBrowser.Api.Images
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         public object Get(GetStudioImage request)
         public object Get(GetStudioImage request)
         {
         {
-            var kernel = (Kernel)Kernel;
-
-            var item = kernel.LibraryManager.GetStudio(request.Name).Result;
+            var item = _libraryManager.GetStudio(request.Name).Result;
 
 
             return GetImage(request, item);
             return GetImage(request, item);
         }
         }
@@ -209,9 +211,7 @@ namespace MediaBrowser.Api.Images
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         public object Get(GetPersonImage request)
         public object Get(GetPersonImage request)
         {
         {
-            var kernel = (Kernel)Kernel;
-
-            var item = kernel.LibraryManager.GetPerson(request.Name).Result;
+            var item = _libraryManager.GetPerson(request.Name).Result;
 
 
             return GetImage(request, item);
             return GetImage(request, item);
         }
         }
@@ -223,9 +223,7 @@ namespace MediaBrowser.Api.Images
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         public object Get(GetGenreImage request)
         public object Get(GetGenreImage request)
         {
         {
-            var kernel = (Kernel)Kernel;
-
-            var item = kernel.LibraryManager.GetGenre(request.Name).Result;
+            var item = _libraryManager.GetGenre(request.Name).Result;
 
 
             return GetImage(request, item);
             return GetImage(request, item);
         }
         }

+ 13 - 23
MediaBrowser.Api/Library/LibraryService.cs

@@ -93,13 +93,14 @@ namespace MediaBrowser.Api.Library
         /// The _app host
         /// The _app host
         /// </summary>
         /// </summary>
         private readonly IApplicationHost _appHost;
         private readonly IApplicationHost _appHost;
+        private readonly ILibraryManager _libraryManager;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="LibraryService" /> class.
         /// Initializes a new instance of the <see cref="LibraryService" /> class.
         /// </summary>
         /// </summary>
         /// <param name="appHost">The app host.</param>
         /// <param name="appHost">The app host.</param>
         /// <exception cref="System.ArgumentNullException">appHost</exception>
         /// <exception cref="System.ArgumentNullException">appHost</exception>
-        public LibraryService(IApplicationHost appHost)
+        public LibraryService(IApplicationHost appHost, ILibraryManager libraryManager)
         {
         {
             if (appHost == null)
             if (appHost == null)
             {
             {
@@ -107,6 +108,7 @@ namespace MediaBrowser.Api.Library
             }
             }
 
 
             _appHost = appHost;
             _appHost = appHost;
+            _libraryManager = libraryManager;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -116,14 +118,12 @@ namespace MediaBrowser.Api.Library
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         public object Get(GetPerson request)
         public object Get(GetPerson request)
         {
         {
-            var kernel = (Kernel)Kernel;
-
-            var item = kernel.LibraryManager.GetPerson(request.Name).Result;
+            var item = _libraryManager.GetPerson(request.Name).Result;
 
 
             // Get everything
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
-            
-            var result = new DtoBuilder(Logger).GetDtoBaseItem(item, fields.ToList()).Result;
+
+            var result = new DtoBuilder(Logger).GetDtoBaseItem(item, fields.ToList(), _libraryManager).Result;
 
 
             return ToOptimizedResult(result);
             return ToOptimizedResult(result);
         }
         }
@@ -135,14 +135,12 @@ namespace MediaBrowser.Api.Library
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         public object Get(GetGenre request)
         public object Get(GetGenre request)
         {
         {
-            var kernel = (Kernel)Kernel;
-
-            var item = kernel.LibraryManager.GetGenre(request.Name).Result;
+            var item = _libraryManager.GetGenre(request.Name).Result;
 
 
             // Get everything
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
 
 
-            var result = new DtoBuilder(Logger).GetDtoBaseItem(item, fields.ToList()).Result;
+            var result = new DtoBuilder(Logger).GetDtoBaseItem(item, fields.ToList(), _libraryManager).Result;
 
 
             return ToOptimizedResult(result);
             return ToOptimizedResult(result);
         }
         }
@@ -154,14 +152,12 @@ namespace MediaBrowser.Api.Library
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         public object Get(GetStudio request)
         public object Get(GetStudio request)
         {
         {
-            var kernel = (Kernel)Kernel;
-
-            var item = kernel.LibraryManager.GetStudio(request.Name).Result;
+            var item = _libraryManager.GetStudio(request.Name).Result;
 
 
             // Get everything
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
 
 
-            var result = new DtoBuilder(Logger).GetDtoBaseItem(item, fields.ToList()).Result;
+            var result = new DtoBuilder(Logger).GetDtoBaseItem(item, fields.ToList(), _libraryManager).Result;
 
 
             return ToOptimizedResult(result);
             return ToOptimizedResult(result);
         }
         }
@@ -173,14 +169,12 @@ namespace MediaBrowser.Api.Library
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         public object Get(GetYear request)
         public object Get(GetYear request)
         {
         {
-            var kernel = (Kernel)Kernel;
-
-            var item = kernel.LibraryManager.GetYear(request.Year).Result;
+            var item = _libraryManager.GetYear(request.Year).Result;
 
 
             // Get everything
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
 
 
-            var result = new DtoBuilder(Logger).GetDtoBaseItem(item, fields.ToList()).Result;
+            var result = new DtoBuilder(Logger).GetDtoBaseItem(item, fields.ToList(), _libraryManager).Result;
 
 
             return ToOptimizedResult(result);
             return ToOptimizedResult(result);
         }
         }
@@ -192,9 +186,7 @@ namespace MediaBrowser.Api.Library
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         public object Get(GetPhyscialPaths request)
         public object Get(GetPhyscialPaths request)
         {
         {
-            var kernel = (Kernel)Kernel;
-
-            var result = kernel.RootFolder.Children.SelectMany(c => c.ResolveArgs.PhysicalLocations).ToList();
+            var result = _libraryManager.RootFolder.Children.SelectMany(c => c.ResolveArgs.PhysicalLocations).ToList();
 
 
             return ToOptimizedResult(result);
             return ToOptimizedResult(result);
         }
         }
@@ -206,8 +198,6 @@ namespace MediaBrowser.Api.Library
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         public object Get(GetItemTypes request)
         public object Get(GetItemTypes request)
         {
         {
-            var kernel = (Kernel)Kernel;
-
             var allTypes = _appHost.AllConcreteTypes.Where(t => t.IsSubclassOf(typeof(BaseItem)));
             var allTypes = _appHost.AllConcreteTypes.Where(t => t.IsSubclassOf(typeof(BaseItem)));
 
 
             if (request.HasInternetProvider)
             if (request.HasInternetProvider)

+ 9 - 5
MediaBrowser.Api/Library/LibraryStructureService.cs

@@ -141,13 +141,18 @@ namespace MediaBrowser.Api.Library
         /// </summary>
         /// </summary>
         private readonly IUserManager _userManager;
         private readonly IUserManager _userManager;
 
 
+        /// <summary>
+        /// The _library manager
+        /// </summary>
+        private readonly ILibraryManager _libraryManager;
+        
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="LibraryService" /> class.
         /// Initializes a new instance of the <see cref="LibraryService" /> class.
         /// </summary>
         /// </summary>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="userManager">The user manager.</param>
         /// <param name="userManager">The user manager.</param>
         /// <exception cref="System.ArgumentNullException">appHost</exception>
         /// <exception cref="System.ArgumentNullException">appHost</exception>
-        public LibraryStructureService(IServerApplicationPaths appPaths, IUserManager userManager)
+        public LibraryStructureService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager)
         {
         {
             if (appPaths == null)
             if (appPaths == null)
             {
             {
@@ -156,6 +161,7 @@ namespace MediaBrowser.Api.Library
 
 
             _userManager = userManager;
             _userManager = userManager;
             _appPaths = appPaths;
             _appPaths = appPaths;
+            _libraryManager = libraryManager;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -165,11 +171,9 @@ namespace MediaBrowser.Api.Library
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         public object Get(GetVirtualFolders request)
         public object Get(GetVirtualFolders request)
         {
         {
-            var kernel = (Kernel)Kernel;
-
             if (string.IsNullOrEmpty(request.UserId))
             if (string.IsNullOrEmpty(request.UserId))
             {
             {
-                var result = kernel.LibraryManager.GetDefaultVirtualFolders().ToList();
+                var result = _libraryManager.GetDefaultVirtualFolders().ToList();
 
 
                 return ToOptimizedResult(result);
                 return ToOptimizedResult(result);
             }
             }
@@ -177,7 +181,7 @@ namespace MediaBrowser.Api.Library
             {
             {
                 var user = _userManager.GetUserById(new Guid(request.UserId));
                 var user = _userManager.GetUserById(new Guid(request.UserId));
 
 
-                var result = kernel.LibraryManager.GetVirtualFolders(user).ToList();
+                var result = _libraryManager.GetVirtualFolders(user).ToList();
 
 
                 return ToOptimizedResult(result);
                 return ToOptimizedResult(result);
             }
             }

+ 2 - 1
MediaBrowser.Api/MediaBrowser.Api.csproj

@@ -140,7 +140,8 @@
   <ItemGroup />
   <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
   <PropertyGroup>
-    <PostBuildEvent>xcopy "$(TargetPath)" "$(SolutionDir)\MediaBrowser.ServerApplication\CorePlugins\" /y</PostBuildEvent>
+    <PostBuildEvent>
+    </PostBuildEvent>
   </PropertyGroup>
   </PropertyGroup>
   <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
   <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 

+ 10 - 2
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -34,6 +34,12 @@ namespace MediaBrowser.Api.Playback
         /// </summary>
         /// </summary>
         /// <value>The user manager.</value>
         /// <value>The user manager.</value>
         protected IUserManager UserManager { get; set; }
         protected IUserManager UserManager { get; set; }
+
+        /// <summary>
+        /// Gets or sets the library manager.
+        /// </summary>
+        /// <value>The library manager.</value>
+        protected ILibraryManager LibraryManager { get; set; }
         
         
         /// <summary>
         /// <summary>
         /// Gets the server kernel.
         /// Gets the server kernel.
@@ -49,10 +55,12 @@ namespace MediaBrowser.Api.Playback
         /// </summary>
         /// </summary>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="userManager">The user manager.</param>
         /// <param name="userManager">The user manager.</param>
-        protected BaseStreamingService(IServerApplicationPaths appPaths, IUserManager userManager)
+        /// <param name="libraryManager">The library manager.</param>
+        protected BaseStreamingService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager)
         {
         {
             ApplicationPaths = appPaths;
             ApplicationPaths = appPaths;
             UserManager = userManager;
             UserManager = userManager;
+            LibraryManager = libraryManager;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -614,7 +622,7 @@ namespace MediaBrowser.Api.Playback
         /// <returns>StreamState.</returns>
         /// <returns>StreamState.</returns>
         protected StreamState GetState(StreamRequest request)
         protected StreamState GetState(StreamRequest request)
         {
         {
-            var item = DtoBuilder.GetItemByClientId(request.Id, UserManager);
+            var item = DtoBuilder.GetItemByClientId(request.Id, UserManager, LibraryManager);
 
 
             var media = (IHasMediaStreams)item;
             var media = (IHasMediaStreams)item;
 
 

+ 2 - 1
MediaBrowser.Api/Playback/Hls/AudioHlsService.cs

@@ -15,7 +15,8 @@ namespace MediaBrowser.Api.Playback.Hls
         /// </summary>
         /// </summary>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="userManager">The user manager.</param>
         /// <param name="userManager">The user manager.</param>
-        public AudioHlsService(IServerApplicationPaths appPaths, IUserManager userManager) : base(appPaths, userManager)
+        public AudioHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager)
+            : base(appPaths, userManager, libraryManager)
         {
         {
         }
         }
 
 

+ 3 - 3
MediaBrowser.Api/Playback/Hls/BaseHlsService.cs

@@ -16,9 +16,9 @@ namespace MediaBrowser.Api.Playback.Hls
         /// The segment file prefix
         /// The segment file prefix
         /// </summary>
         /// </summary>
         public const string SegmentFilePrefix = "segment-";
         public const string SegmentFilePrefix = "segment-";
-        
-        protected BaseHlsService(IServerApplicationPaths appPaths, IUserManager userManager)
-            : base(appPaths, userManager)
+
+        protected BaseHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager)
+            : base(appPaths, userManager, libraryManager)
         {
         {
         }
         }
 
 

+ 2 - 2
MediaBrowser.Api/Playback/Hls/VideoHlsService.cs

@@ -11,8 +11,8 @@ namespace MediaBrowser.Api.Playback.Hls
         /// </summary>
         /// </summary>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="userManager">The user manager.</param>
         /// <param name="userManager">The user manager.</param>
-        public VideoHlsService(IServerApplicationPaths appPaths, IUserManager userManager)
-            : base(appPaths, userManager)
+        public VideoHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager)
+            : base(appPaths, userManager, libraryManager)
         {
         {
         }
         }
 
 

+ 2 - 2
MediaBrowser.Api/Playback/Progressive/AudioService.cs

@@ -28,8 +28,8 @@ namespace MediaBrowser.Api.Playback.Progressive
         /// Initializes a new instance of the <see cref="BaseProgressiveStreamingService" /> class.
         /// Initializes a new instance of the <see cref="BaseProgressiveStreamingService" /> class.
         /// </summary>
         /// </summary>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="appPaths">The app paths.</param>
-        public AudioService(IServerApplicationPaths appPaths, IUserManager userManager)
-            : base(appPaths, userManager)
+        public AudioService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager)
+            : base(appPaths, userManager, libraryManager)
         {
         {
         }
         }
 
 

+ 2 - 2
MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs

@@ -18,8 +18,8 @@ namespace MediaBrowser.Api.Playback.Progressive
         /// Initializes a new instance of the <see cref="BaseProgressiveStreamingService" /> class.
         /// Initializes a new instance of the <see cref="BaseProgressiveStreamingService" /> class.
         /// </summary>
         /// </summary>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="appPaths">The app paths.</param>
-        protected BaseProgressiveStreamingService(IServerApplicationPaths appPaths, IUserManager userManager)
-            : base(appPaths, userManager)
+        protected BaseProgressiveStreamingService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager)
+            : base(appPaths, userManager, libraryManager)
         {
         {
         }
         }
 
 

+ 2 - 2
MediaBrowser.Api/Playback/Progressive/VideoService.cs

@@ -34,8 +34,8 @@ namespace MediaBrowser.Api.Playback.Progressive
         /// Initializes a new instance of the <see cref="BaseProgressiveStreamingService" /> class.
         /// Initializes a new instance of the <see cref="BaseProgressiveStreamingService" /> class.
         /// </summary>
         /// </summary>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="appPaths">The app paths.</param>
-        public VideoService(IServerApplicationPaths appPaths, IUserManager userManager)
-            : base(appPaths, userManager)
+        public VideoService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager)
+            : base(appPaths, userManager, libraryManager)
         {
         {
         }
         }
 
 

+ 5 - 3
MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs

@@ -24,14 +24,16 @@ namespace MediaBrowser.Api.UserLibrary
         /// The _user manager
         /// The _user manager
         /// </summary>
         /// </summary>
         protected readonly IUserManager UserManager;
         protected readonly IUserManager UserManager;
+        protected readonly ILibraryManager LibraryManager;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="BaseItemsByNameService{TItemType}" /> class.
         /// Initializes a new instance of the <see cref="BaseItemsByNameService{TItemType}" /> class.
         /// </summary>
         /// </summary>
         /// <param name="userManager">The user manager.</param>
         /// <param name="userManager">The user manager.</param>
-        protected BaseItemsByNameService(IUserManager userManager)
+        protected BaseItemsByNameService(IUserManager userManager, ILibraryManager libraryManager)
         {
         {
             UserManager = userManager;
             UserManager = userManager;
+            LibraryManager = libraryManager;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -43,7 +45,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
         {
             var user = UserManager.GetUserById(request.UserId);
             var user = UserManager.GetUserById(request.UserId);
 
 
-            var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, UserManager, user.Id);
+            var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, UserManager, LibraryManager, user.Id);
 
 
             IEnumerable<BaseItem> items;
             IEnumerable<BaseItem> items;
 
 
@@ -126,7 +128,7 @@ namespace MediaBrowser.Api.UserLibrary
                 return null;
                 return null;
             }
             }
 
 
-            var dto = await new DtoBuilder(Logger).GetDtoBaseItem(item, user, fields).ConfigureAwait(false);
+            var dto = await new DtoBuilder(Logger).GetDtoBaseItem(item, user, fields, LibraryManager).ConfigureAwait(false);
 
 
             dto.ChildCount = stub.Item2();
             dto.ChildCount = stub.Item2();
 
 

+ 4 - 7
MediaBrowser.Api/UserLibrary/GenresService.cs

@@ -1,6 +1,4 @@
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using ServiceStack.ServiceHost;
 using ServiceStack.ServiceHost;
 using System;
 using System;
@@ -24,7 +22,8 @@ namespace MediaBrowser.Api.UserLibrary
     /// </summary>
     /// </summary>
     public class GenresService : BaseItemsByNameService<Genre>
     public class GenresService : BaseItemsByNameService<Genre>
     {
     {
-        public GenresService(IUserManager userManager) : base(userManager)
+        public GenresService(IUserManager userManager, ILibraryManager libraryManager)
+            : base(userManager, libraryManager)
         {
         {
         }
         }
 
 
@@ -64,9 +63,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>Task{Genre}.</returns>
         /// <returns>Task{Genre}.</returns>
         protected override Task<Genre> GetEntity(string name)
         protected override Task<Genre> GetEntity(string name)
         {
         {
-            var kernel = (Kernel)Kernel;
-
-            return kernel.LibraryManager.GetGenre(name);
+            return LibraryManager.GetGenre(name);
         }
         }
     }
     }
 }
 }

+ 9 - 3
MediaBrowser.Api/UserLibrary/ItemsService.cs

@@ -150,13 +150,19 @@ namespace MediaBrowser.Api.UserLibrary
         /// </summary>
         /// </summary>
         private readonly IUserManager _userManager;
         private readonly IUserManager _userManager;
 
 
+        /// <summary>
+        /// The _library manager
+        /// </summary>
+        private readonly ILibraryManager _libraryManager;
+        
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="ItemsService" /> class.
         /// Initializes a new instance of the <see cref="ItemsService" /> class.
         /// </summary>
         /// </summary>
         /// <param name="userManager">The user manager.</param>
         /// <param name="userManager">The user manager.</param>
-        public ItemsService(IUserManager userManager)
+        public ItemsService(IUserManager userManager, ILibraryManager libraryManager)
         {
         {
             _userManager = userManager;
             _userManager = userManager;
+            _libraryManager = libraryManager;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -203,7 +209,7 @@ namespace MediaBrowser.Api.UserLibrary
 
 
             var dtoBuilder = new DtoBuilder(Logger);
             var dtoBuilder = new DtoBuilder(Logger);
 
 
-            var returnItems = await Task.WhenAll(pagedItems.Select(i => dtoBuilder.GetDtoBaseItem(i, user, fields))).ConfigureAwait(false);
+            var returnItems = await Task.WhenAll(pagedItems.Select(i => dtoBuilder.GetDtoBaseItem(i, user, fields, _libraryManager))).ConfigureAwait(false);
 
 
             return new ItemsResult
             return new ItemsResult
             {
             {
@@ -221,7 +227,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <exception cref="System.InvalidOperationException"></exception>
         /// <exception cref="System.InvalidOperationException"></exception>
         private IEnumerable<BaseItem> GetItemsToSerialize(GetItems request, User user)
         private IEnumerable<BaseItem> GetItemsToSerialize(GetItems request, User user)
         {
         {
-            var item = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.ParentId, _userManager, user.Id);
+            var item = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.ParentId, _userManager, _libraryManager, user.Id);
 
 
             // Default list type = children
             // Default list type = children
 
 

+ 3 - 4
MediaBrowser.Api/UserLibrary/PersonsService.cs

@@ -29,7 +29,8 @@ namespace MediaBrowser.Api.UserLibrary
     /// </summary>
     /// </summary>
     public class PersonsService : BaseItemsByNameService<Person>
     public class PersonsService : BaseItemsByNameService<Person>
     {
     {
-        public PersonsService(IUserManager userManager) : base(userManager)
+        public PersonsService(IUserManager userManager, ILibraryManager libraryManager)
+            : base(userManager, libraryManager)
         {
         {
         }
         }
 
 
@@ -98,9 +99,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>Task{Genre}.</returns>
         /// <returns>Task{Genre}.</returns>
         protected override Task<Person> GetEntity(string name)
         protected override Task<Person> GetEntity(string name)
         {
         {
-            var kernel = (Kernel)Kernel;
-
-            return kernel.LibraryManager.GetPerson(name);
+            return LibraryManager.GetPerson(name);
         }
         }
     }
     }
 }
 }

+ 4 - 7
MediaBrowser.Api/UserLibrary/StudiosService.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using ServiceStack.ServiceHost;
 using ServiceStack.ServiceHost;
 using System;
 using System;
@@ -23,8 +22,8 @@ namespace MediaBrowser.Api.UserLibrary
     /// </summary>
     /// </summary>
     public class StudiosService : BaseItemsByNameService<Studio>
     public class StudiosService : BaseItemsByNameService<Studio>
     {
     {
-        public StudiosService(IUserManager userManager)
-            : base(userManager)
+        public StudiosService(IUserManager userManager, ILibraryManager libraryManager)
+            : base(userManager, libraryManager)
         {
         {
         }
         }
 
 
@@ -64,9 +63,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>Task{Studio}.</returns>
         /// <returns>Task{Studio}.</returns>
         protected override Task<Studio> GetEntity(string name)
         protected override Task<Studio> GetEntity(string name)
         {
         {
-            var kernel = (Kernel)Kernel;
-
-            return kernel.LibraryManager.GetStudio(name);
+            return LibraryManager.GetStudio(name);
         }
         }
     }
     }
 }
 }

+ 21 - 20
MediaBrowser.Api/UserLibrary/UserLibraryService.cs

@@ -316,13 +316,15 @@ namespace MediaBrowser.Api.UserLibrary
         /// The _user manager
         /// The _user manager
         /// </summary>
         /// </summary>
         private readonly IUserManager _userManager;
         private readonly IUserManager _userManager;
+
+        private readonly ILibraryManager _libraryManager;
         
         
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="UserLibraryService" /> class.
         /// Initializes a new instance of the <see cref="UserLibraryService" /> class.
         /// </summary>
         /// </summary>
         /// <param name="jsonSerializer">The json serializer.</param>
         /// <param name="jsonSerializer">The json serializer.</param>
         /// <exception cref="System.ArgumentNullException">jsonSerializer</exception>
         /// <exception cref="System.ArgumentNullException">jsonSerializer</exception>
-        public UserLibraryService(IJsonSerializer jsonSerializer, IUserManager userManager)
+        public UserLibraryService(IJsonSerializer jsonSerializer, IUserManager userManager, ILibraryManager libraryManager)
             : base()
             : base()
         {
         {
             if (jsonSerializer == null)
             if (jsonSerializer == null)
@@ -332,6 +334,7 @@ namespace MediaBrowser.Api.UserLibrary
 
 
             _jsonSerializer = jsonSerializer;
             _jsonSerializer = jsonSerializer;
             _userManager = userManager;
             _userManager = userManager;
+            _libraryManager = libraryManager;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -343,7 +346,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
         {
             var user = _userManager.GetUserById(request.UserId);
             var user = _userManager.GetUserById(request.UserId);
 
 
-            var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, user.Id);
+            var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
 
 
             // Get everything
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
@@ -352,7 +355,7 @@ namespace MediaBrowser.Api.UserLibrary
 
 
             var dtoBuilder = new DtoBuilder(Logger);
             var dtoBuilder = new DtoBuilder(Logger);
 
 
-            var items = movie.SpecialFeatures.Select(i => dtoBuilder.GetDtoBaseItem(item, user, fields)).AsParallel().Select(t => t.Result).ToList();
+            var items = movie.SpecialFeatures.Select(i => dtoBuilder.GetDtoBaseItem(item, user, fields, _libraryManager)).AsParallel().Select(t => t.Result).ToList();
 
 
             return ToOptimizedResult(items);
             return ToOptimizedResult(items);
         }
         }
@@ -366,14 +369,14 @@ namespace MediaBrowser.Api.UserLibrary
         {
         {
             var user = _userManager.GetUserById(request.UserId);
             var user = _userManager.GetUserById(request.UserId);
 
 
-            var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, user.Id);
+            var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
 
 
             // Get everything
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
 
 
             var dtoBuilder = new DtoBuilder(Logger);
             var dtoBuilder = new DtoBuilder(Logger);
 
 
-            var items = item.LocalTrailers.Select(i => dtoBuilder.GetDtoBaseItem(item, user, fields)).AsParallel().Select(t => t.Result).ToList();
+            var items = item.LocalTrailers.Select(i => dtoBuilder.GetDtoBaseItem(item, user, fields, _libraryManager)).AsParallel().Select(t => t.Result).ToList();
 
 
             return ToOptimizedResult(items);
             return ToOptimizedResult(items);
         }
         }
@@ -387,14 +390,14 @@ namespace MediaBrowser.Api.UserLibrary
         {
         {
             var user = _userManager.GetUserById(request.UserId);
             var user = _userManager.GetUserById(request.UserId);
 
 
-            var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, user.Id);
+            var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
 
 
             // Get everything
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
 
 
             var dtoBuilder = new DtoBuilder(Logger);
             var dtoBuilder = new DtoBuilder(Logger);
 
 
-            var result = dtoBuilder.GetDtoBaseItem(item, user, fields).Result;
+            var result = dtoBuilder.GetDtoBaseItem(item, user, fields, _libraryManager).Result;
 
 
             return ToOptimizedResult(result);
             return ToOptimizedResult(result);
         }
         }
@@ -410,7 +413,7 @@ namespace MediaBrowser.Api.UserLibrary
 
 
             var user = _userManager.GetUserById(request.UserId);
             var user = _userManager.GetUserById(request.UserId);
 
 
-            var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, user.Id);
+            var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
 
 
             var result = kernel.IntroProviders.SelectMany(i => i.GetIntros(item, user));
             var result = kernel.IntroProviders.SelectMany(i => i.GetIntros(item, user));
 
 
@@ -429,15 +432,13 @@ namespace MediaBrowser.Api.UserLibrary
             var userId = new Guid(pathInfo.GetArgumentValue<string>(1));
             var userId = new Guid(pathInfo.GetArgumentValue<string>(1));
             var itemId = pathInfo.GetArgumentValue<string>(3);
             var itemId = pathInfo.GetArgumentValue<string>(3);
 
 
-            var kernel = (Kernel)Kernel;
-
             var user = _userManager.GetUserById(userId);
             var user = _userManager.GetUserById(userId);
 
 
-            var item = (Folder)DtoBuilder.GetItemByClientId(itemId, _userManager, user.Id);
+            var item = (Folder)DtoBuilder.GetItemByClientId(itemId, _userManager, _libraryManager, user.Id);
 
 
             var displayPreferences = _jsonSerializer.DeserializeFromStream<DisplayPreferences>(request.RequestStream);
             var displayPreferences = _jsonSerializer.DeserializeFromStream<DisplayPreferences>(request.RequestStream);
 
 
-            var task = kernel.LibraryManager.SaveDisplayPreferencesForFolder(user, item, displayPreferences);
+            var task = _libraryManager.SaveDisplayPreferencesForFolder(user, item, displayPreferences);
 
 
             Task.WaitAll(task);
             Task.WaitAll(task);
         }
         }
@@ -450,7 +451,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
         {
             var user = _userManager.GetUserById(request.UserId);
             var user = _userManager.GetUserById(request.UserId);
 
 
-            var item = (Folder)DtoBuilder.GetItemByClientId(request.Id, _userManager, user.Id);
+            var item = (Folder)DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
 
 
             // Get the user data for this item
             // Get the user data for this item
             var data = item.GetUserData(user, true);
             var data = item.GetUserData(user, true);
@@ -471,7 +472,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
         {
             var user = _userManager.GetUserById(request.UserId);
             var user = _userManager.GetUserById(request.UserId);
 
 
-            var item = (Folder)DtoBuilder.GetItemByClientId(request.Id, _userManager, user.Id);
+            var item = (Folder)DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
 
 
             // Get the user data for this item
             // Get the user data for this item
             var data = item.GetUserData(user, true);
             var data = item.GetUserData(user, true);
@@ -492,7 +493,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
         {
             var user = _userManager.GetUserById(request.UserId);
             var user = _userManager.GetUserById(request.UserId);
 
 
-            var item = (Folder)DtoBuilder.GetItemByClientId(request.Id, _userManager, user.Id);
+            var item = (Folder)DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
 
 
             // Get the user data for this item
             // Get the user data for this item
             var data = item.GetUserData(user, true);
             var data = item.GetUserData(user, true);
@@ -512,7 +513,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
         {
             var user = _userManager.GetUserById(request.UserId);
             var user = _userManager.GetUserById(request.UserId);
 
 
-            var item = (Folder)DtoBuilder.GetItemByClientId(request.Id, _userManager, user.Id);
+            var item = (Folder)DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
 
 
             // Get the user data for this item
             // Get the user data for this item
             var data = item.GetUserData(user, true);
             var data = item.GetUserData(user, true);
@@ -545,7 +546,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
         {
             var user = _userManager.GetUserById(request.UserId);
             var user = _userManager.GetUserById(request.UserId);
 
 
-            var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, user.Id);
+            var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
 
 
             _userManager.OnPlaybackStart(user, item, ClientType.Other, string.Empty);
             _userManager.OnPlaybackStart(user, item, ClientType.Other, string.Empty);
         }
         }
@@ -558,7 +559,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
         {
             var user = _userManager.GetUserById(request.UserId);
             var user = _userManager.GetUserById(request.UserId);
 
 
-            var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, user.Id);
+            var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
 
 
             var task = _userManager.OnPlaybackProgress(user, item, request.PositionTicks, ClientType.Other, string.Empty);
             var task = _userManager.OnPlaybackProgress(user, item, request.PositionTicks, ClientType.Other, string.Empty);
 
 
@@ -573,7 +574,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
         {
             var user = _userManager.GetUserById(request.UserId);
             var user = _userManager.GetUserById(request.UserId);
 
 
-            var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, user.Id);
+            var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
 
 
             var task = _userManager.OnPlaybackStopped(user, item, request.PositionTicks, ClientType.Other, string.Empty);
             var task = _userManager.OnPlaybackStopped(user, item, request.PositionTicks, ClientType.Other, string.Empty);
 
 
@@ -602,7 +603,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>Task.</returns>
         /// <returns>Task.</returns>
         private Task UpdatePlayedStatus(User user, string itemId, bool wasPlayed)
         private Task UpdatePlayedStatus(User user, string itemId, bool wasPlayed)
         {
         {
-            var item = DtoBuilder.GetItemByClientId(itemId, _userManager, user.Id);
+            var item = DtoBuilder.GetItemByClientId(itemId, _userManager, _libraryManager, user.Id);
 
 
             return item.SetPlayedStatus(user, wasPlayed, _userManager);
             return item.SetPlayedStatus(user, wasPlayed, _userManager);
         }
         }

+ 5 - 8
MediaBrowser.Api/UserLibrary/YearsService.cs

@@ -1,6 +1,4 @@
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using ServiceStack.ServiceHost;
 using ServiceStack.ServiceHost;
 using System;
 using System;
@@ -29,8 +27,9 @@ namespace MediaBrowser.Api.UserLibrary
         /// The us culture
         /// The us culture
         /// </summary>
         /// </summary>
         private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
         private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
-        public YearsService(IUserManager userManager) : base(userManager)
+        
+        public YearsService(IUserManager userManager, ILibraryManager libraryManager)
+            : base(userManager, libraryManager)
         {
         {
         }
         }
 
 
@@ -70,9 +69,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>Task{Studio}.</returns>
         /// <returns>Task{Studio}.</returns>
         protected override Task<Year> GetEntity(string name)
         protected override Task<Year> GetEntity(string name)
         {
         {
-            var kernel = (Kernel)Kernel;
-
-            return kernel.LibraryManager.GetYear(int.Parse(name, UsCulture));
+            return LibraryManager.GetYear(int.Parse(name, UsCulture));
         }
         }
     }
     }
 }
 }

+ 19 - 13
MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs

@@ -244,21 +244,27 @@ namespace MediaBrowser.Common.Implementations.NetworkManagement
         /// <exception cref="System.ArgumentException">Unknown share type</exception>
         /// <exception cref="System.ArgumentException">Unknown share type</exception>
         private NetworkShareType ToNetworkShareType(ShareType shareType)
         private NetworkShareType ToNetworkShareType(ShareType shareType)
         {
         {
-            switch (shareType)
+            if (shareType.HasFlag(ShareType.Special))
             {
             {
-                case ShareType.Device:
-                    return NetworkShareType.Device;
-                case ShareType.Disk :
-                    return NetworkShareType.Disk;
-                case ShareType.IPC :
-                    return NetworkShareType.Ipc;
-                case ShareType.Printer :
-                    return NetworkShareType.Printer;
-                case ShareType.Special:
-                    return NetworkShareType.Special;
-                default:
-                    throw new ArgumentException("Unknown share type");
+                return NetworkShareType.Special;
             }
             }
+            if (shareType.HasFlag(ShareType.Device))
+            {
+                return NetworkShareType.Device;
+            }
+            if (shareType.HasFlag(ShareType.Disk))
+            {
+                return NetworkShareType.Disk;
+            }
+            if (shareType.HasFlag(ShareType.IPC))
+            {
+                return NetworkShareType.Ipc;
+            }
+            if (shareType.HasFlag(ShareType.Printer))
+            {
+                return NetworkShareType.Printer;
+            }
+            throw new ArgumentException("Unknown share type");
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 39 - 5
MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs

@@ -65,6 +65,31 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
         /// <param name="serverManager">The server manager.</param>
         /// <param name="serverManager">The server manager.</param>
         public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, IJsonSerializer jsonSerializer, ILogger logger, IServerManager serverManager)
         public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, IJsonSerializer jsonSerializer, ILogger logger, IServerManager serverManager)
         {
         {
+            if (scheduledTask == null)
+            {
+                throw new ArgumentNullException("scheduledTask");
+            }
+            if (applicationPaths == null)
+            {
+                throw new ArgumentNullException("applicationPaths");
+            }
+            if (taskManager == null)
+            {
+                throw new ArgumentNullException("taskManager");
+            }
+            if (jsonSerializer == null)
+            {
+                throw new ArgumentNullException("jsonSerializer");
+            }
+            if (logger == null)
+            {
+                throw new ArgumentNullException("logger");
+            }
+            if (serverManager == null)
+            {
+                throw new ArgumentNullException("serverManager");
+            }
+
             ScheduledTask = scheduledTask;
             ScheduledTask = scheduledTask;
             ApplicationPaths = applicationPaths;
             ApplicationPaths = applicationPaths;
             TaskManager = taskManager;
             TaskManager = taskManager;
@@ -316,7 +341,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
 
 
             try
             try
             {
             {
-                await System.Threading.Tasks.Task.Run(async () => await ScheduledTask.Execute(CurrentCancellationTokenSource.Token, progress).ConfigureAwait(false)).ConfigureAwait(false);
+                await ExecuteTask(CurrentCancellationTokenSource.Token, progress).ConfigureAwait(false);
 
 
                 status = TaskCompletionStatus.Completed;
                 status = TaskCompletionStatus.Completed;
             }
             }
@@ -334,8 +359,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
             var startTime = CurrentExecutionStartTime;
             var startTime = CurrentExecutionStartTime;
             var endTime = DateTime.UtcNow;
             var endTime = DateTime.UtcNow;
 
 
-            ServerManager.SendWebSocketMessage("ScheduledTaskEndExecute", LastExecutionResult);
-
             progress.ProgressChanged -= progress_ProgressChanged;
             progress.ProgressChanged -= progress_ProgressChanged;
             CurrentCancellationTokenSource.Dispose();
             CurrentCancellationTokenSource.Dispose();
             CurrentCancellationTokenSource = null;
             CurrentCancellationTokenSource = null;
@@ -344,6 +367,11 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
             OnTaskCompleted(startTime, endTime, status);
             OnTaskCompleted(startTime, endTime, status);
         }
         }
 
 
+        private Task ExecuteTask(CancellationToken cancellationToken, IProgress<double> progress)
+        {
+            return Task.Run(async () => await ScheduledTask.Execute(cancellationToken, progress).ConfigureAwait(false));
+        }
+
         /// <summary>
         /// <summary>
         /// Progress_s the progress changed.
         /// Progress_s the progress changed.
         /// </summary>
         /// </summary>
@@ -482,7 +510,8 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
         /// <param name="startTime">The start time.</param>
         /// <param name="startTime">The start time.</param>
         /// <param name="endTime">The end time.</param>
         /// <param name="endTime">The end time.</param>
         /// <param name="status">The status.</param>
         /// <param name="status">The status.</param>
-        private void OnTaskCompleted(DateTime startTime, DateTime endTime, TaskCompletionStatus status)
+        /// <param name="sendNotification">if set to <c>true</c> [send notification].</param>
+        private void OnTaskCompleted(DateTime startTime, DateTime endTime, TaskCompletionStatus status, bool sendNotification = true)
         {
         {
             var elapsedTime = endTime - startTime;
             var elapsedTime = endTime - startTime;
 
 
@@ -500,6 +529,11 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
             JsonSerializer.SerializeToFile(result, GetHistoryFilePath());
             JsonSerializer.SerializeToFile(result, GetHistoryFilePath());
 
 
             LastExecutionResult = result;
             LastExecutionResult = result;
+
+            if (sendNotification)
+            {
+                ServerManager.SendWebSocketMessage("ScheduledTaskEndExecute", result);
+            }
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -523,7 +557,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
 
 
                 if (State == TaskState.Running)
                 if (State == TaskState.Running)
                 {
                 {
-                    OnTaskCompleted(CurrentExecutionStartTime, DateTime.UtcNow, TaskCompletionStatus.Aborted);
+                    OnTaskCompleted(CurrentExecutionStartTime, DateTime.UtcNow, TaskCompletionStatus.Aborted, false);
                 }
                 }
 
 
                 if (CurrentCancellationTokenSource != null)
                 if (CurrentCancellationTokenSource != null)

+ 2 - 1
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -95,6 +95,7 @@ namespace MediaBrowser.Controller.Entities
         /// The logger
         /// The logger
         /// </summary>
         /// </summary>
         protected static internal ILogger Logger { get; internal set; }
         protected static internal ILogger Logger { get; internal set; }
+        protected static internal ILibraryManager LibraryManager { get; internal set; }
 
 
         /// <summary>
         /// <summary>
         /// Returns a <see cref="System.String" /> that represents this instance.
         /// Returns a <see cref="System.String" /> that represents this instance.
@@ -613,7 +614,7 @@ namespace MediaBrowser.Controller.Entities
                 return new List<Video> { };
                 return new List<Video> { };
             }
             }
 
 
-            return Kernel.Instance.LibraryManager.GetItems<Video>(files, null).Select(video =>
+            return LibraryManager.ResolvePaths<Video>(files, null).Select(video =>
             {
             {
                 // Try to retrieve it from the db. If we don't find it, use the resolved version
                 // Try to retrieve it from the db. If we don't find it, use the resolved version
                 var dbItem = Kernel.Instance.ItemRepository.RetrieveItem(video.Id) as Video;
                 var dbItem = Kernel.Instance.ItemRepository.RetrieveItem(video.Id) as Video;

+ 1 - 1
MediaBrowser.Controller/Entities/CollectionFolder.cs

@@ -88,7 +88,7 @@ namespace MediaBrowser.Controller.Entities
                 }
                 }
 
 
                 var ourChildren =
                 var ourChildren =
-                    Kernel.Instance.RootFolder.Children.OfType<Folder>()
+                    LibraryManager.RootFolder.Children.OfType<Folder>()
                           .Where(i => folderIds.Contains(i.Id))
                           .Where(i => folderIds.Contains(i.Id))
                           .SelectMany(c => c.Children);
                           .SelectMany(c => c.Children);
 
 

+ 6 - 6
MediaBrowser.Controller/Entities/Folder.cs

@@ -317,7 +317,7 @@ namespace MediaBrowser.Controller.Entities
                     {
                     {
                         try
                         try
                         {
                         {
-                            return Kernel.Instance.LibraryManager.GetPerson(i).Result;
+                            return LibraryManager.GetPerson(i).Result;
                         }
                         }
                         catch (IOException ex)
                         catch (IOException ex)
                         {
                         {
@@ -359,7 +359,7 @@ namespace MediaBrowser.Controller.Entities
                     {
                     {
                         try
                         try
                         {
                         {
-                            return Kernel.Instance.LibraryManager.GetStudio(i).Result;
+                            return LibraryManager.GetStudio(i).Result;
                         }
                         }
                         catch (IOException ex)
                         catch (IOException ex)
                         {
                         {
@@ -399,7 +399,7 @@ namespace MediaBrowser.Controller.Entities
                         {
                         {
                             try
                             try
                             {
                             {
-                                return Kernel.Instance.LibraryManager.GetGenre(i).Result;
+                                return LibraryManager.GetGenre(i).Result;
                             }
                             }
                             catch (IOException ex)
                             catch (IOException ex)
                             {
                             {
@@ -440,7 +440,7 @@ namespace MediaBrowser.Controller.Entities
                     {
                     {
                         try
                         try
                         {
                         {
-                            return Kernel.Instance.LibraryManager.GetYear(i).Result;
+                            return LibraryManager.GetYear(i).Result;
                         }
                         }
                         catch (IOException ex)
                         catch (IOException ex)
                         {
                         {
@@ -768,7 +768,7 @@ namespace MediaBrowser.Controller.Entities
                 IndexCache.Clear();
                 IndexCache.Clear();
 
 
                 //and fire event
                 //and fire event
-                Kernel.Instance.LibraryManager.OnLibraryChanged(changedArgs);
+                LibraryManager.ReportLibraryChanged(changedArgs);
             }
             }
 
 
             progress.Report(15);
             progress.Report(15);
@@ -860,7 +860,7 @@ namespace MediaBrowser.Controller.Entities
                 return new List<BaseItem> { };
                 return new List<BaseItem> { };
             }
             }
 
 
-            return Kernel.Instance.LibraryManager.GetItems<BaseItem>(fileSystemChildren, this);
+            return LibraryManager.ResolvePaths<BaseItem>(fileSystemChildren, this);
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 1 - 1
MediaBrowser.Controller/Entities/Movies/Movie.cs

@@ -181,7 +181,7 @@ namespace MediaBrowser.Controller.Entities.Movies
                 return new List<Video> { };
                 return new List<Video> { };
             }
             }
 
 
-            return Kernel.Instance.LibraryManager.GetItems<Video>(files, null).Select(video =>
+            return LibraryManager.ResolvePaths<Video>(files, null).Select(video =>
             {
             {
                 // Try to retrieve it from the db. If we don't find it, use the resolved version
                 // Try to retrieve it from the db. If we don't find it, use the resolved version
                 var dbItem = Kernel.Instance.ItemRepository.RetrieveItem(video.Id) as Video;
                 var dbItem = Kernel.Instance.ItemRepository.RetrieveItem(video.Id) as Video;

+ 1 - 1
MediaBrowser.Controller/Entities/User.cs

@@ -124,7 +124,7 @@ namespace MediaBrowser.Controller.Entities
         {
         {
             get
             get
             {
             {
-                LazyInitializer.EnsureInitialized(ref _rootFolder, ref _userRootFolderInitialized, ref _userRootFolderSyncLock, () => (UserRootFolder)Kernel.Instance.LibraryManager.GetItem(RootFolderPath));
+                LazyInitializer.EnsureInitialized(ref _rootFolder, ref _userRootFolderInitialized, ref _userRootFolderSyncLock, () => (UserRootFolder)LibraryManager.ResolvePath(RootFolderPath));
                 return _rootFolder;
                 return _rootFolder;
             }
             }
             private set
             private set

+ 1 - 1
MediaBrowser.Controller/Entities/UserRootFolder.cs

@@ -15,7 +15,7 @@ namespace MediaBrowser.Controller.Entities
         /// <returns>IEnumerable{BaseItem}.</returns>
         /// <returns>IEnumerable{BaseItem}.</returns>
         protected override IEnumerable<BaseItem> GetNonCachedChildren()
         protected override IEnumerable<BaseItem> GetNonCachedChildren()
         {
         {
-            return base.GetNonCachedChildren().Concat(Kernel.Instance.RootFolder.VirtualChildren);
+            return base.GetNonCachedChildren().Concat(LibraryManager.RootFolder.VirtualChildren);
         }
         }
     }
     }
 }
 }

+ 11 - 8
MediaBrowser.Controller/IO/DirectoryWatchers.cs

@@ -72,11 +72,13 @@ namespace MediaBrowser.Controller.IO
         /// </summary>
         /// </summary>
         /// <value>The task manager.</value>
         /// <value>The task manager.</value>
         private ITaskManager TaskManager { get; set; }
         private ITaskManager TaskManager { get; set; }
-        
+
+        private ILibraryManager LibraryManager { get; set; }
+
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="DirectoryWatchers" /> class.
         /// Initializes a new instance of the <see cref="DirectoryWatchers" /> class.
         /// </summary>
         /// </summary>
-        public DirectoryWatchers(ILogger logger, ITaskManager taskManager)
+        public DirectoryWatchers(ILogger logger, ITaskManager taskManager, ILibraryManager libraryManager)
         {
         {
             if (logger == null)
             if (logger == null)
             {
             {
@@ -87,6 +89,7 @@ namespace MediaBrowser.Controller.IO
                 throw new ArgumentNullException("taskManager");
                 throw new ArgumentNullException("taskManager");
             }
             }
 
 
+            LibraryManager = libraryManager;
             TaskManager = taskManager;
             TaskManager = taskManager;
             Logger = logger;
             Logger = logger;
         }
         }
@@ -96,11 +99,11 @@ namespace MediaBrowser.Controller.IO
         /// </summary>
         /// </summary>
         internal void Start()
         internal void Start()
         {
         {
-            Kernel.Instance.LibraryManager.LibraryChanged += Instance_LibraryChanged;
-          
-            var pathsToWatch = new List<string> { Kernel.Instance.RootFolder.Path };
+            LibraryManager.LibraryChanged += Instance_LibraryChanged;
+
+            var pathsToWatch = new List<string> { LibraryManager.RootFolder.Path };
 
 
-            var paths = Kernel.Instance.RootFolder.Children.OfType<Folder>()
+            var paths = LibraryManager.RootFolder.Children.OfType<Folder>()
                 .SelectMany(f =>
                 .SelectMany(f =>
                     {
                     {
                         try
                         try
@@ -467,7 +470,7 @@ namespace MediaBrowser.Controller.IO
 
 
             while (item == null && !string.IsNullOrEmpty(path))
             while (item == null && !string.IsNullOrEmpty(path))
             {
             {
-                item = Kernel.Instance.RootFolder.FindByPath(path);
+                item = LibraryManager.RootFolder.FindByPath(path);
 
 
                 path = Path.GetDirectoryName(path);
                 path = Path.GetDirectoryName(path);
             }
             }
@@ -494,7 +497,7 @@ namespace MediaBrowser.Controller.IO
         /// </summary>
         /// </summary>
         private void Stop()
         private void Stop()
         {
         {
-            Kernel.Instance.LibraryManager.LibraryChanged -= Instance_LibraryChanged;
+            LibraryManager.LibraryChanged -= Instance_LibraryChanged;
 
 
             FileSystemWatcher watcher;
             FileSystemWatcher watcher;
 
 

+ 4 - 2
MediaBrowser.Controller/IO/FileSystemManager.cs

@@ -2,6 +2,7 @@
 using MediaBrowser.Common.Kernel;
 using MediaBrowser.Common.Kernel;
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
 using System;
 using System;
 using System.IO;
 using System.IO;
@@ -34,11 +35,12 @@ namespace MediaBrowser.Controller.IO
         /// <param name="kernel">The kernel.</param>
         /// <param name="kernel">The kernel.</param>
         /// <param name="logger">The logger.</param>
         /// <param name="logger">The logger.</param>
         /// <param name="taskManager">The task manager.</param>
         /// <param name="taskManager">The task manager.</param>
-        public FileSystemManager(Kernel kernel, ILogger logger, ITaskManager taskManager)
+        /// <param name="libraryManager">The library manager.</param>
+        public FileSystemManager(Kernel kernel, ILogger logger, ITaskManager taskManager, ILibraryManager libraryManager)
             : base(kernel)
             : base(kernel)
         {
         {
             _logger = logger;
             _logger = logger;
-            DirectoryWatchers = new DirectoryWatchers(logger, taskManager);
+            DirectoryWatchers = new DirectoryWatchers(logger, taskManager, libraryManager);
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 5 - 91
MediaBrowser.Controller/Kernel.cs

@@ -36,12 +36,6 @@ namespace MediaBrowser.Controller
         /// <value>The instance.</value>
         /// <value>The instance.</value>
         public static Kernel Instance { get; private set; }
         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>
         /// <summary>
         /// Gets the image manager.
         /// Gets the image manager.
         /// </summary>
         /// </summary>
@@ -72,40 +66,6 @@ namespace MediaBrowser.Controller
         /// <value>The provider manager.</value>
         /// <value>The provider manager.</value>
         public ProviderManager ProviderManager { get; private set; }
         public ProviderManager ProviderManager { get; private set; }
 
 
-        /// <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>
         /// <summary>
         /// Gets the kernel context.
         /// Gets the kernel context.
         /// </summary>
         /// </summary>
@@ -156,13 +116,13 @@ namespace MediaBrowser.Controller
         /// Gets the list of currently registered entity resolvers
         /// Gets the list of currently registered entity resolvers
         /// </summary>
         /// </summary>
         /// <value>The entity resolvers enumerable.</value>
         /// <value>The entity resolvers enumerable.</value>
-        internal IEnumerable<IBaseItemResolver> EntityResolvers { get; private set; }
+        public IEnumerable<IBaseItemResolver> EntityResolvers { get; private set; }
 
 
         /// <summary>
         /// <summary>
         /// Gets the list of BasePluginFolders added by plugins
         /// Gets the list of BasePluginFolders added by plugins
         /// </summary>
         /// </summary>
         /// <value>The plugin folders.</value>
         /// <value>The plugin folders.</value>
-        internal IEnumerable<IVirtualFolderCreator> PluginFolderCreators { get; private set; }
+        public IEnumerable<IVirtualFolderCreator> PluginFolderCreators { get; private set; }
 
 
         /// <summary>
         /// <summary>
         /// Gets the list of available user repositories
         /// Gets the list of available user repositories
@@ -210,7 +170,7 @@ namespace MediaBrowser.Controller
         /// Gets the list of entity resolution ignore rules
         /// Gets the list of entity resolution ignore rules
         /// </summary>
         /// </summary>
         /// <value>The entity resolution ignore rules.</value>
         /// <value>The entity resolution ignore rules.</value>
-        internal IEnumerable<IResolutionIgnoreRule> EntityResolutionIgnoreRules { get; private set; }
+        public IEnumerable<IResolutionIgnoreRule> EntityResolutionIgnoreRules { get; private set; }
 
 
         /// <summary>
         /// <summary>
         /// Gets the active user data repository
         /// Gets the active user data repository
@@ -233,7 +193,6 @@ namespace MediaBrowser.Controller
         /// <param name="appHost">The app host.</param>
         /// <param name="appHost">The app host.</param>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="xmlSerializer">The XML serializer.</param>
         /// <param name="xmlSerializer">The XML serializer.</param>
-        /// <param name="taskManager">The task manager.</param>
         /// <param name="logger">The logger.</param>
         /// <param name="logger">The logger.</param>
         /// <exception cref="System.ArgumentNullException">isoManager</exception>
         /// <exception cref="System.ArgumentNullException">isoManager</exception>
         public Kernel(IApplicationHost appHost, IServerApplicationPaths appPaths, IXmlSerializer xmlSerializer, ILogger logger)
         public Kernel(IApplicationHost appHost, IServerApplicationPaths appPaths, IXmlSerializer xmlSerializer, ILogger logger)
@@ -255,11 +214,11 @@ namespace MediaBrowser.Controller
         protected override void FindParts()
         protected override void FindParts()
         {
         {
             // For now there's no real way to inject this properly
             // For now there's no real way to inject this properly
+            BaseItem.LibraryManager = ApplicationHost.Resolve<ILibraryManager>();
             User.UserManager = ApplicationHost.Resolve<IUserManager>();
             User.UserManager = ApplicationHost.Resolve<IUserManager>();
 
 
             InstallationManager = (InstallationManager)ApplicationHost.CreateInstance(typeof(InstallationManager));
             InstallationManager = (InstallationManager)ApplicationHost.CreateInstance(typeof(InstallationManager));
             FFMpegManager = (FFMpegManager)ApplicationHost.CreateInstance(typeof(FFMpegManager));
             FFMpegManager = (FFMpegManager)ApplicationHost.CreateInstance(typeof(FFMpegManager));
-            LibraryManager = (LibraryManager)ApplicationHost.CreateInstance(typeof(LibraryManager));
             ImageManager = (ImageManager)ApplicationHost.CreateInstance(typeof(ImageManager));
             ImageManager = (ImageManager)ApplicationHost.CreateInstance(typeof(ImageManager));
             ProviderManager = (ProviderManager)ApplicationHost.CreateInstance(typeof(ProviderManager));
             ProviderManager = (ProviderManager)ApplicationHost.CreateInstance(typeof(ProviderManager));
             SecurityManager = (PluginSecurityManager)ApplicationHost.CreateInstance(typeof(PluginSecurityManager));
             SecurityManager = (PluginSecurityManager)ApplicationHost.CreateInstance(typeof(PluginSecurityManager));
@@ -287,9 +246,6 @@ namespace MediaBrowser.Controller
         /// <returns>Task.</returns>
         /// <returns>Task.</returns>
         protected override async Task ReloadInternal()
         protected override async Task ReloadInternal()
         {
         {
-            // Reset these so that they can be lazy loaded again
-            RootFolder = null;
-
             await base.ReloadInternal().ConfigureAwait(false);
             await base.ReloadInternal().ConfigureAwait(false);
 
 
             ReloadResourcePools();
             ReloadResourcePools();
@@ -399,52 +355,10 @@ namespace MediaBrowser.Controller
         {
         {
             DisposeFileSystemManager();
             DisposeFileSystemManager();
 
 
-            FileSystemManager = new FileSystemManager(this, Logger, ApplicationHost.Resolve<ITaskManager>());
+            FileSystemManager = new FileSystemManager(this, Logger, ApplicationHost.Resolve<ITaskManager>(), ApplicationHost.Resolve<ILibraryManager>());
             FileSystemManager.StartWatchers();
             FileSystemManager.StartWatchers();
         }
         }
 
 
-        /// <summary>
-        /// Finds a library item by Id and UserId.
-        /// </summary>
-        /// <param name="id">The id.</param>
-        /// <param name="userId">The user id.</param>
-        /// <param name="userManager">The user manager.</param>
-        /// <returns>BaseItem.</returns>
-        /// <exception cref="System.ArgumentNullException">id</exception>
-        public BaseItem GetItemById(Guid id, Guid userId, IUserManager userManager)
-        {
-            if (id == Guid.Empty)
-            {
-                throw new ArgumentNullException("id");
-            }
-
-            if (userId == Guid.Empty)
-            {
-                throw new ArgumentNullException("userId");
-            }
-
-            var user = userManager.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>
         /// <summary>
         /// Completely overwrites the current configuration with a new copy
         /// Completely overwrites the current configuration with a new copy
         /// </summary>
         /// </summary>

+ 18 - 16
MediaBrowser.Controller/Library/DtoBuilder.cs

@@ -38,7 +38,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="fields">The fields.</param>
         /// <param name="fields">The fields.</param>
         /// <returns>Task{DtoBaseItem}.</returns>
         /// <returns>Task{DtoBaseItem}.</returns>
         /// <exception cref="System.ArgumentNullException">item</exception>
         /// <exception cref="System.ArgumentNullException">item</exception>
-        public async Task<BaseItemDto> GetDtoBaseItem(BaseItem item, List<ItemFields> fields)
+        public async Task<BaseItemDto> GetDtoBaseItem(BaseItem item, List<ItemFields> fields, ILibraryManager libraryManager)
         {
         {
             if (item == null)
             if (item == null)
             {
             {
@@ -73,7 +73,7 @@ namespace MediaBrowser.Controller.Library
 
 
             if (fields.Contains(ItemFields.People))
             if (fields.Contains(ItemFields.People))
             {
             {
-                tasks.Add(AttachPeople(dto, item));
+                tasks.Add(AttachPeople(dto, item, libraryManager));
             }
             }
 
 
             AttachBasicFields(dto, item, fields);
             AttachBasicFields(dto, item, fields);
@@ -86,16 +86,17 @@ namespace MediaBrowser.Controller.Library
 
 
             return dto;
             return dto;
         }
         }
-        
+
         /// <summary>
         /// <summary>
         /// Converts a BaseItem to a DTOBaseItem
         /// Converts a BaseItem to a DTOBaseItem
         /// </summary>
         /// </summary>
         /// <param name="item">The item.</param>
         /// <param name="item">The item.</param>
         /// <param name="user">The user.</param>
         /// <param name="user">The user.</param>
         /// <param name="fields">The fields.</param>
         /// <param name="fields">The fields.</param>
+        /// <param name="libraryManager">The library manager.</param>
         /// <returns>Task{DtoBaseItem}.</returns>
         /// <returns>Task{DtoBaseItem}.</returns>
-        /// <exception cref="System.ArgumentNullException"></exception>
-        public async Task<BaseItemDto> GetDtoBaseItem(BaseItem item, User user, List<ItemFields> fields)
+        /// <exception cref="System.ArgumentNullException">item</exception>
+        public async Task<BaseItemDto> GetDtoBaseItem(BaseItem item, User user, List<ItemFields> fields, ILibraryManager libraryManager)
         {
         {
             if (item == null)
             if (item == null)
             {
             {
@@ -134,7 +135,7 @@ namespace MediaBrowser.Controller.Library
 
 
             if (fields.Contains(ItemFields.People))
             if (fields.Contains(ItemFields.People))
             {
             {
-                tasks.Add(AttachPeople(dto, item));
+                tasks.Add(AttachPeople(dto, item, libraryManager));
             }
             }
 
 
             AttachBasicFields(dto, item, fields);
             AttachBasicFields(dto, item, fields);
@@ -558,8 +559,9 @@ namespace MediaBrowser.Controller.Library
         /// </summary>
         /// </summary>
         /// <param name="dto">The dto.</param>
         /// <param name="dto">The dto.</param>
         /// <param name="item">The item.</param>
         /// <param name="item">The item.</param>
+        /// <param name="libraryManager">The library manager.</param>
         /// <returns>Task.</returns>
         /// <returns>Task.</returns>
-        private async Task AttachPeople(BaseItemDto dto, BaseItem item)
+        private async Task AttachPeople(BaseItemDto dto, BaseItem item, ILibraryManager libraryManager)
         {
         {
             if (item.People == null)
             if (item.People == null)
             {
             {
@@ -575,7 +577,7 @@ namespace MediaBrowser.Controller.Library
                     {
                     {
                         try
                         try
                         {
                         {
-                            return await Kernel.Instance.LibraryManager.GetPerson(c.Name).ConfigureAwait(false);
+                            return await libraryManager.GetPerson(c.Name).ConfigureAwait(false);
                         }
                         }
                         catch (IOException ex)
                         catch (IOException ex)
                         {
                         {
@@ -662,7 +664,7 @@ namespace MediaBrowser.Controller.Library
         /// </summary>
         /// </summary>
         /// <param name="changeEvent">The <see cref="ChildrenChangedEventArgs" /> instance containing the event data.</param>
         /// <param name="changeEvent">The <see cref="ChildrenChangedEventArgs" /> instance containing the event data.</param>
         /// <returns>LibraryUpdateInfo.</returns>
         /// <returns>LibraryUpdateInfo.</returns>
-        internal static LibraryUpdateInfo GetLibraryUpdateInfo(ChildrenChangedEventArgs changeEvent)
+        public static LibraryUpdateInfo GetLibraryUpdateInfo(ChildrenChangedEventArgs changeEvent)
         {
         {
             return new LibraryUpdateInfo
             return new LibraryUpdateInfo
             {
             {
@@ -823,7 +825,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="id">The id.</param>
         /// <param name="id">The id.</param>
         /// <param name="userId">The user id.</param>
         /// <param name="userId">The user id.</param>
         /// <returns>BaseItem.</returns>
         /// <returns>BaseItem.</returns>
-        public static BaseItem GetItemByClientId(string id, IUserManager userManager, Guid? userId = null)
+        public static BaseItem GetItemByClientId(string id, IUserManager userManager, ILibraryManager libraryManager, Guid? userId = null)
         {
         {
             var isIdEmpty = string.IsNullOrEmpty(id);
             var isIdEmpty = string.IsNullOrEmpty(id);
 
 
@@ -835,7 +837,7 @@ namespace MediaBrowser.Controller.Library
             {
             {
                 if (userId.HasValue)
                 if (userId.HasValue)
                 {
                 {
-                    return GetIndexFolder(id, userId.Value, userManager);
+                    return GetIndexFolder(id, userId.Value, userManager, libraryManager);
                 }
                 }
             }
             }
 
 
@@ -845,11 +847,11 @@ namespace MediaBrowser.Controller.Library
             {
             {
                 item = isIdEmpty
                 item = isIdEmpty
                            ? userManager.GetUserById(userId.Value).RootFolder
                            ? userManager.GetUserById(userId.Value).RootFolder
-                           : Kernel.Instance.GetItemById(new Guid(id), userId.Value, userManager);
+                           : libraryManager.GetItemById(new Guid(id), userId.Value);
             }
             }
             else if (!isIndexFolder)
             else if (!isIndexFolder)
             {
             {
-                item = Kernel.Instance.GetItemById(new Guid(id));
+                item = libraryManager.GetItemById(new Guid(id));
             }
             }
 
 
             // If we still don't find it, look within individual user views
             // If we still don't find it, look within individual user views
@@ -857,7 +859,7 @@ namespace MediaBrowser.Controller.Library
             {
             {
                 foreach (var user in userManager.Users)
                 foreach (var user in userManager.Users)
                 {
                 {
-                    item = GetItemByClientId(id, userManager, user.Id);
+                    item = GetItemByClientId(id, userManager, libraryManager, user.Id);
 
 
                     if (item != null)
                     if (item != null)
                     {
                     {
@@ -875,7 +877,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="id">The id.</param>
         /// <param name="id">The id.</param>
         /// <param name="userId">The user id.</param>
         /// <param name="userId">The user id.</param>
         /// <returns>BaseItem.</returns>
         /// <returns>BaseItem.</returns>
-        private static BaseItem GetIndexFolder(string id, Guid userId, IUserManager userManager)
+        private static BaseItem GetIndexFolder(string id, Guid userId, IUserManager userManager, ILibraryManager libraryManager)
         {
         {
             var user = userManager.GetUserById(userId);
             var user = userManager.GetUserById(userId);
 
 
@@ -885,7 +887,7 @@ namespace MediaBrowser.Controller.Library
             var values = id.Split(stringSeparators, StringSplitOptions.None).ToList();
             var values = id.Split(stringSeparators, StringSplitOptions.None).ToList();
 
 
             // Get the top folder normally using the first id
             // Get the top folder normally using the first id
-            var folder = GetItemByClientId(values[0], userManager, userId) as Folder;
+            var folder = GetItemByClientId(values[0], userManager, libraryManager, userId) as Folder;
 
 
             values.RemoveAt(0);
             values.RemoveAt(0);
 
 

+ 145 - 0
MediaBrowser.Controller/Library/ILibraryManager.cs

@@ -0,0 +1,145 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.IO;
+using MediaBrowser.Model.Entities;
+
+namespace MediaBrowser.Controller.Library
+{
+    public interface ILibraryManager
+    {
+        /// <summary>
+        /// Fires whenever any validation routine adds or removes items.  The added and removed items are properties of the args.
+        /// *** Will fire asynchronously. ***
+        /// </summary>
+        event EventHandler<ChildrenChangedEventArgs> LibraryChanged;
+
+        /// <summary>
+        /// Raises the <see cref="E:LibraryChanged" /> event.
+        /// </summary>
+        /// <param name="args">The <see cref="ChildrenChangedEventArgs" /> instance containing the event data.</param>
+        void ReportLibraryChanged(ChildrenChangedEventArgs args);
+
+        /// <summary>
+        /// Resolves the item.
+        /// </summary>
+        /// <param name="args">The args.</param>
+        /// <returns>BaseItem.</returns>
+        BaseItem ResolveItem(ItemResolveArgs args);
+
+        /// <summary>
+        /// Resolves a path into a BaseItem
+        /// </summary>
+        /// <param name="path">The path.</param>
+        /// <param name="parent">The parent.</param>
+        /// <param name="fileInfo">The file info.</param>
+        /// <returns>BaseItem.</returns>
+        /// <exception cref="System.ArgumentNullException"></exception>
+        BaseItem ResolvePath(string path, Folder parent = null, WIN32_FIND_DATA? fileInfo = null);
+
+        /// <summary>
+        /// Resolves a set of files into a list of BaseItem
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="files">The files.</param>
+        /// <param name="parent">The parent.</param>
+        /// <returns>List{``0}.</returns>
+        List<T> ResolvePaths<T>(IEnumerable<WIN32_FIND_DATA> files, Folder parent) 
+            where T : BaseItem;
+
+        /// <summary>
+        /// Gets the root folder.
+        /// </summary>
+        /// <value>The root folder.</value>
+        AggregateFolder RootFolder { get; }
+
+        /// <summary>
+        /// Gets a Person
+        /// </summary>
+        /// <param name="name">The name.</param>
+        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
+        /// <returns>Task{Person}.</returns>
+        Task<Person> GetPerson(string name, bool allowSlowProviders = false);
+
+        /// <summary>
+        /// Gets a Studio
+        /// </summary>
+        /// <param name="name">The name.</param>
+        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
+        /// <returns>Task{Studio}.</returns>
+        Task<Studio> GetStudio(string name, bool allowSlowProviders = false);
+
+        /// <summary>
+        /// Gets a Genre
+        /// </summary>
+        /// <param name="name">The name.</param>
+        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
+        /// <returns>Task{Genre}.</returns>
+        Task<Genre> GetGenre(string name, bool allowSlowProviders = false);
+
+        /// <summary>
+        /// Gets a Year
+        /// </summary>
+        /// <param name="value">The value.</param>
+        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
+        /// <returns>Task{Year}.</returns>
+        /// <exception cref="System.ArgumentOutOfRangeException"></exception>
+        Task<Year> GetYear(int value, bool allowSlowProviders = false);
+
+        /// <summary>
+        /// Validate and refresh the People sub-set of the IBN.
+        /// The items are stored in the db but not loaded into memory until actually requested by an operation.
+        /// </summary>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <param name="progress">The progress.</param>
+        /// <returns>Task.</returns>
+        Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress);
+
+        /// <summary>
+        /// Reloads the root media folder
+        /// </summary>
+        /// <param name="progress">The progress.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task.</returns>
+        Task ValidateMediaLibrary(IProgress<double> progress, CancellationToken cancellationToken);
+
+        /// <summary>
+        /// Saves display preferences for a Folder
+        /// </summary>
+        /// <param name="user">The user.</param>
+        /// <param name="folder">The folder.</param>
+        /// <param name="data">The data.</param>
+        /// <returns>Task.</returns>
+        Task SaveDisplayPreferencesForFolder(User user, Folder folder, DisplayPreferences data);
+
+        /// <summary>
+        /// Gets the default view.
+        /// </summary>
+        /// <returns>IEnumerable{VirtualFolderInfo}.</returns>
+        IEnumerable<VirtualFolderInfo> GetDefaultVirtualFolders();
+
+        /// <summary>
+        /// Gets the view.
+        /// </summary>
+        /// <param name="user">The user.</param>
+        /// <returns>IEnumerable{VirtualFolderInfo}.</returns>
+        IEnumerable<VirtualFolderInfo> GetVirtualFolders(User user);
+
+        /// <summary>
+        /// Gets the item by id.
+        /// </summary>
+        /// <param name="id">The id.</param>
+        /// <returns>BaseItem.</returns>
+        BaseItem GetItemById(Guid id);
+
+        /// <summary>
+        /// Gets the item by id.
+        /// </summary>
+        /// <param name="id">The id.</param>
+        /// <param name="userId">The user id.</param>
+        /// <returns>BaseItem.</returns>
+        BaseItem GetItemById(Guid id, Guid userId);
+    }
+}

+ 1 - 1
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -113,6 +113,7 @@
     <Compile Include="IServerApplicationPaths.cs" />
     <Compile Include="IServerApplicationPaths.cs" />
     <Compile Include="Library\ChildrenChangedEventArgs.cs" />
     <Compile Include="Library\ChildrenChangedEventArgs.cs" />
     <Compile Include="Library\DtoBuilder.cs" />
     <Compile Include="Library\DtoBuilder.cs" />
+    <Compile Include="Library\ILibraryManager.cs" />
     <Compile Include="Library\IUserManager.cs" />
     <Compile Include="Library\IUserManager.cs" />
     <Compile Include="Library\Profiler.cs" />
     <Compile Include="Library\Profiler.cs" />
     <Compile Include="Localization\AURatingsDictionary.cs" />
     <Compile Include="Localization\AURatingsDictionary.cs" />
@@ -181,7 +182,6 @@
     <Compile Include="Library\ItemResolveArgs.cs" />
     <Compile Include="Library\ItemResolveArgs.cs" />
     <Compile Include="IO\DirectoryWatchers.cs" />
     <Compile Include="IO\DirectoryWatchers.cs" />
     <Compile Include="IO\FileData.cs" />
     <Compile Include="IO\FileData.cs" />
-    <Compile Include="Library\LibraryManager.cs" />
     <Compile Include="Kernel.cs" />
     <Compile Include="Kernel.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Providers\BaseMetadataProvider.cs" />
     <Compile Include="Providers\BaseMetadataProvider.cs" />

+ 9 - 5
MediaBrowser.Controller/ScheduledTasks/PeopleValidationTask.cs

@@ -1,4 +1,5 @@
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Common.ScheduledTasks;
+using MediaBrowser.Controller.Library;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Threading;
 using System.Threading;
@@ -11,15 +12,18 @@ namespace MediaBrowser.Controller.ScheduledTasks
     /// </summary>
     /// </summary>
     public class PeopleValidationTask : IScheduledTask
     public class PeopleValidationTask : IScheduledTask
     {
     {
-        private readonly Kernel _kernel;
+        /// <summary>
+        /// The _library manager
+        /// </summary>
+        private readonly ILibraryManager _libraryManager;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="PeopleValidationTask" /> class.
         /// Initializes a new instance of the <see cref="PeopleValidationTask" /> class.
         /// </summary>
         /// </summary>
-        /// <param name="kernel">The kernel.</param>
-        public PeopleValidationTask(Kernel kernel)
+        /// <param name="libraryManager">The library manager.</param>
+        public PeopleValidationTask(ILibraryManager libraryManager)
         {
         {
-            _kernel = kernel;
+            _libraryManager = libraryManager;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -44,7 +48,7 @@ namespace MediaBrowser.Controller.ScheduledTasks
         /// <returns>Task.</returns>
         /// <returns>Task.</returns>
         public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
         public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
         {
         {
-            return _kernel.LibraryManager.ValidatePeople(cancellationToken, progress);
+            return _libraryManager.ValidatePeople(cancellationToken, progress);
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 7 - 6
MediaBrowser.Controller/ScheduledTasks/RefreshMediaLibraryTask.cs

@@ -1,4 +1,5 @@
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Common.ScheduledTasks;
+using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Tasks;
 using MediaBrowser.Model.Tasks;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -13,17 +14,17 @@ namespace MediaBrowser.Controller.ScheduledTasks
     public class RefreshMediaLibraryTask : IScheduledTask
     public class RefreshMediaLibraryTask : IScheduledTask
     {
     {
         /// <summary>
         /// <summary>
-        /// The _kernel
+        /// The _library manager
         /// </summary>
         /// </summary>
-        private readonly Kernel _kernel;
+        private readonly ILibraryManager _libraryManager;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="RefreshMediaLibraryTask" /> class.
         /// Initializes a new instance of the <see cref="RefreshMediaLibraryTask" /> class.
         /// </summary>
         /// </summary>
-        /// <param name="kernel">The kernel.</param>
-        public RefreshMediaLibraryTask(Kernel kernel)
+        /// <param name="libraryManager">The library manager.</param>
+        public RefreshMediaLibraryTask(ILibraryManager libraryManager)
         {
         {
-            _kernel = kernel;
+            _libraryManager = libraryManager;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -54,7 +55,7 @@ namespace MediaBrowser.Controller.ScheduledTasks
 
 
             progress.Report(0);
             progress.Report(0);
 
 
-            return _kernel.LibraryManager.ValidateMediaLibrary(progress, cancellationToken);
+            return _libraryManager.ValidateMediaLibrary(progress, cancellationToken);
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 3 - 2
BDInfo/BdInfoExaminer.cs → MediaBrowser.Server.Implementations/BdInfo/BdInfoExaminer.cs

@@ -1,10 +1,11 @@
-using MediaBrowser.Model.Entities;
+using BDInfo;
+using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.MediaInfo;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 
 
-namespace BDInfo
+namespace MediaBrowser.Server.Implementations.BdInfo
 {
 {
     /// <summary>
     /// <summary>
     /// Class BdInfoExaminer
     /// Class BdInfoExaminer

+ 98 - 16
MediaBrowser.Controller/Library/LibraryManager.cs → MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -1,8 +1,10 @@
 using MediaBrowser.Common.Events;
 using MediaBrowser.Common.Events;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Common.ScheduledTasks;
+using MediaBrowser.Controller;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.IO;
+using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Resolvers;
 using MediaBrowser.Controller.Resolvers;
 using MediaBrowser.Controller.ScheduledTasks;
 using MediaBrowser.Controller.ScheduledTasks;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
@@ -17,12 +19,12 @@ using System.Linq;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
-namespace MediaBrowser.Controller.Library
+namespace MediaBrowser.Server.Implementations.Library
 {
 {
     /// <summary>
     /// <summary>
     /// Class LibraryManager
     /// Class LibraryManager
     /// </summary>
     /// </summary>
-    public class LibraryManager
+    public class LibraryManager : ILibraryManager
     {
     {
         #region LibraryChanged Event
         #region LibraryChanged Event
         /// <summary>
         /// <summary>
@@ -35,7 +37,7 @@ namespace MediaBrowser.Controller.Library
         /// Raises the <see cref="E:LibraryChanged" /> event.
         /// Raises the <see cref="E:LibraryChanged" /> event.
         /// </summary>
         /// </summary>
         /// <param name="args">The <see cref="ChildrenChangedEventArgs" /> instance containing the event data.</param>
         /// <param name="args">The <see cref="ChildrenChangedEventArgs" /> instance containing the event data.</param>
-        internal void OnLibraryChanged(ChildrenChangedEventArgs args)
+        public void ReportLibraryChanged(ChildrenChangedEventArgs args)
         {
         {
             EventHelper.QueueEventIfNotNull(LibraryChanged, this, args, _logger);
             EventHelper.QueueEventIfNotNull(LibraryChanged, this, args, _logger);
 
 
@@ -64,8 +66,11 @@ namespace MediaBrowser.Controller.Library
         /// </summary>
         /// </summary>
         private readonly ITaskManager _taskManager;
         private readonly ITaskManager _taskManager;
 
 
+        /// <summary>
+        /// The _user manager
+        /// </summary>
         private readonly IUserManager _userManager;
         private readonly IUserManager _userManager;
-        
+
         /// <summary>
         /// <summary>
         /// Gets or sets the kernel.
         /// Gets or sets the kernel.
         /// </summary>
         /// </summary>
@@ -78,6 +83,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="kernel">The kernel.</param>
         /// <param name="kernel">The kernel.</param>
         /// <param name="logger">The logger.</param>
         /// <param name="logger">The logger.</param>
         /// <param name="taskManager">The task manager.</param>
         /// <param name="taskManager">The task manager.</param>
+        /// <param name="userManager">The user manager.</param>
         public LibraryManager(Kernel kernel, ILogger logger, ITaskManager taskManager, IUserManager userManager)
         public LibraryManager(Kernel kernel, ILogger logger, ITaskManager taskManager, IUserManager userManager)
         {
         {
             Kernel = kernel;
             Kernel = kernel;
@@ -88,6 +94,40 @@ namespace MediaBrowser.Controller.Library
             kernel.ConfigurationUpdated += kernel_ConfigurationUpdated;
             kernel.ConfigurationUpdated += kernel_ConfigurationUpdated;
         }
         }
 
 
+        /// <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, CreateRootFolder);
+                return _rootFolder;
+            }
+            private set
+            {
+                _rootFolder = value;
+
+                if (value == null)
+                {
+                    _rootFolderInitialized = false;
+                }
+            }
+        }
+
         /// <summary>
         /// <summary>
         /// Handles the ConfigurationUpdated event of the kernel control.
         /// Handles the ConfigurationUpdated event of the kernel control.
         /// </summary>
         /// </summary>
@@ -133,7 +173,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="fileInfo">The file info.</param>
         /// <param name="fileInfo">The file info.</param>
         /// <returns>BaseItem.</returns>
         /// <returns>BaseItem.</returns>
         /// <exception cref="System.ArgumentNullException"></exception>
         /// <exception cref="System.ArgumentNullException"></exception>
-        public BaseItem GetItem(string path, Folder parent = null, WIN32_FIND_DATA? fileInfo = null)
+        public BaseItem ResolvePath(string path, Folder parent = null, WIN32_FIND_DATA? fileInfo = null)
         {
         {
             if (string.IsNullOrEmpty(path))
             if (string.IsNullOrEmpty(path))
             {
             {
@@ -185,7 +225,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="files">The files.</param>
         /// <param name="files">The files.</param>
         /// <param name="parent">The parent.</param>
         /// <param name="parent">The parent.</param>
         /// <returns>List{``0}.</returns>
         /// <returns>List{``0}.</returns>
-        public List<T> GetItems<T>(IEnumerable<WIN32_FIND_DATA> files, Folder parent)
+        public List<T> ResolvePaths<T>(IEnumerable<WIN32_FIND_DATA> files, Folder parent)
             where T : BaseItem
             where T : BaseItem
         {
         {
             var list = new List<T>();
             var list = new List<T>();
@@ -194,7 +234,7 @@ namespace MediaBrowser.Controller.Library
             {
             {
                 try
                 try
                 {
                 {
-                    var item = GetItem(f.Path, parent, f) as T;
+                    var item = ResolvePath(f.Path, parent, f) as T;
 
 
                     if (item != null)
                     if (item != null)
                     {
                     {
@@ -218,7 +258,7 @@ namespace MediaBrowser.Controller.Library
         /// </summary>
         /// </summary>
         /// <returns>AggregateFolder.</returns>
         /// <returns>AggregateFolder.</returns>
         /// <exception cref="System.InvalidOperationException">Cannot create the root folder until plugins have loaded</exception>
         /// <exception cref="System.InvalidOperationException">Cannot create the root folder until plugins have loaded</exception>
-        internal AggregateFolder CreateRootFolder()
+        public AggregateFolder CreateRootFolder()
         {
         {
             if (Kernel.Plugins == null)
             if (Kernel.Plugins == null)
             {
             {
@@ -226,7 +266,7 @@ namespace MediaBrowser.Controller.Library
             }
             }
 
 
             var rootFolderPath = Kernel.ApplicationPaths.RootFolderPath;
             var rootFolderPath = Kernel.ApplicationPaths.RootFolderPath;
-            var rootFolder = Kernel.ItemRepository.RetrieveItem(rootFolderPath.GetMBId(typeof(AggregateFolder))) as AggregateFolder ?? (AggregateFolder)GetItem(rootFolderPath);
+            var rootFolder = Kernel.ItemRepository.RetrieveItem(rootFolderPath.GetMBId(typeof(AggregateFolder))) as AggregateFolder ?? (AggregateFolder)ResolvePath(rootFolderPath);
 
 
             // Add in the plug-in folders
             // Add in the plug-in folders
             foreach (var child in Kernel.PluginFolderCreators)
             foreach (var child in Kernel.PluginFolderCreators)
@@ -412,7 +452,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <param name="progress">The progress.</param>
         /// <param name="progress">The progress.</param>
         /// <returns>Task.</returns>
         /// <returns>Task.</returns>
-        internal async Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress)
+        public async Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress)
         {
         {
             // Clear the IBN cache
             // Clear the IBN cache
             ImagesByNameItemCache.Clear();
             ImagesByNameItemCache.Clear();
@@ -423,7 +463,7 @@ namespace MediaBrowser.Controller.Library
 
 
             var includedPersonTypes = new[] { PersonType.Actor, PersonType.Director };
             var includedPersonTypes = new[] { PersonType.Actor, PersonType.Director };
 
 
-            var people = Kernel.RootFolder.RecursiveChildren
+            var people = RootFolder.RecursiveChildren
                 .Where(c => c.People != null)
                 .Where(c => c.People != null)
                 .SelectMany(c => c.People.Where(p => includedPersonTypes.Contains(p.Type)))
                 .SelectMany(c => c.People.Where(p => includedPersonTypes.Contains(p.Type)))
                 .DistinctBy(p => p.Name, StringComparer.OrdinalIgnoreCase)
                 .DistinctBy(p => p.Name, StringComparer.OrdinalIgnoreCase)
@@ -483,21 +523,21 @@ namespace MediaBrowser.Controller.Library
         /// <param name="progress">The progress.</param>
         /// <param name="progress">The progress.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task.</returns>
         /// <returns>Task.</returns>
-        internal async Task ValidateMediaLibrary(IProgress<double> progress, CancellationToken cancellationToken)
+        public async Task ValidateMediaLibrary(IProgress<double> progress, CancellationToken cancellationToken)
         {
         {
             _logger.Info("Validating media library");
             _logger.Info("Validating media library");
 
 
-            await Kernel.RootFolder.RefreshMetadata(cancellationToken).ConfigureAwait(false);
+            await RootFolder.RefreshMetadata(cancellationToken).ConfigureAwait(false);
 
 
             // Start by just validating the children of the root, but go no further
             // Start by just validating the children of the root, but go no further
-            await Kernel.RootFolder.ValidateChildren(new Progress<double> { }, cancellationToken, recursive: false);
+            await RootFolder.ValidateChildren(new Progress<double> { }, cancellationToken, recursive: false);
 
 
             // Validate only the collection folders for each user, just to make them available as quickly as possible
             // Validate only the collection folders for each user, just to make them available as quickly as possible
             var userCollectionFolderTasks = _userManager.Users.AsParallel().Select(user => user.ValidateCollectionFolders(new Progress<double> { }, cancellationToken));
             var userCollectionFolderTasks = _userManager.Users.AsParallel().Select(user => user.ValidateCollectionFolders(new Progress<double> { }, cancellationToken));
             await Task.WhenAll(userCollectionFolderTasks).ConfigureAwait(false);
             await Task.WhenAll(userCollectionFolderTasks).ConfigureAwait(false);
 
 
             // Now validate the entire media library
             // Now validate the entire media library
-            await Kernel.RootFolder.ValidateChildren(progress, cancellationToken, recursive: true).ConfigureAwait(false);
+            await RootFolder.ValidateChildren(progress, cancellationToken, recursive: true).ConfigureAwait(false);
 
 
             foreach (var user in _userManager.Users)
             foreach (var user in _userManager.Users)
             {
             {
@@ -515,7 +555,7 @@ namespace MediaBrowser.Controller.Library
         public Task SaveDisplayPreferencesForFolder(User user, Folder folder, DisplayPreferences data)
         public Task SaveDisplayPreferencesForFolder(User user, Folder folder, DisplayPreferences data)
         {
         {
             // Need to update all items with the same DisplayPrefsId
             // Need to update all items with the same DisplayPrefsId
-            foreach (var child in Kernel.RootFolder.GetRecursiveChildren(user)
+            foreach (var child in RootFolder.GetRecursiveChildren(user)
                 .OfType<Folder>()
                 .OfType<Folder>()
                 .Where(i => i.DisplayPrefsId == folder.DisplayPrefsId))
                 .Where(i => i.DisplayPrefsId == folder.DisplayPrefsId))
             {
             {
@@ -558,5 +598,47 @@ namespace MediaBrowser.Controller.Library
                     Locations = Directory.EnumerateFiles(dir, "*.lnk", SearchOption.TopDirectoryOnly).Select(FileSystem.ResolveShortcut).ToList()
                     Locations = Directory.EnumerateFiles(dir, "*.lnk", SearchOption.TopDirectoryOnly).Select(FileSystem.ResolveShortcut).ToList()
                 });
                 });
         }
         }
+
+        /// <summary>
+        /// Finds a library item by Id and UserId.
+        /// </summary>
+        /// <param name="id">The id.</param>
+        /// <param name="userId">The user id.</param>
+        /// <param name="userManager">The user manager.</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 = _userManager.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 null;
+            //return RootFolder.FindItemById(id, null);
+        }
     }
     }
 }
 }

+ 9 - 0
MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj

@@ -32,6 +32,9 @@
     <WarningLevel>4</WarningLevel>
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   </PropertyGroup>
   <ItemGroup>
   <ItemGroup>
+    <Reference Include="MoreLinq">
+      <HintPath>..\packages\morelinq.1.0.15631-beta\lib\net35\MoreLinq.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Core" />
     <Reference Include="System.Data.SQLite">
     <Reference Include="System.Data.SQLite">
@@ -50,6 +53,8 @@
     <Compile Include="..\SharedVersion.cs">
     <Compile Include="..\SharedVersion.cs">
       <Link>Properties\SharedVersion.cs</Link>
       <Link>Properties\SharedVersion.cs</Link>
     </Compile>
     </Compile>
+    <Compile Include="BdInfo\BdInfoExaminer.cs" />
+    <Compile Include="Library\LibraryManager.cs" />
     <Compile Include="Library\UserManager.cs" />
     <Compile Include="Library\UserManager.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Reflection\TypeMapper.cs" />
     <Compile Include="Reflection\TypeMapper.cs" />
@@ -66,6 +71,10 @@
     <Compile Include="WorldWeatherOnline\WeatherProvider.cs" />
     <Compile Include="WorldWeatherOnline\WeatherProvider.cs" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\BDInfo\BDInfo.csproj">
+      <Project>{07b509c0-0c28-4f3f-8963-5263281f7e3d}</Project>
+      <Name>BDInfo</Name>
+    </ProjectReference>
     <ProjectReference Include="..\MediaBrowser.Common.Implementations\MediaBrowser.Common.Implementations.csproj">
     <ProjectReference Include="..\MediaBrowser.Common.Implementations\MediaBrowser.Common.Implementations.csproj">
       <Project>{c4d2573a-3fd3-441f-81af-174ac4cd4e1d}</Project>
       <Project>{c4d2573a-3fd3-441f-81af-174ac4cd4e1d}</Project>
       <Name>MediaBrowser.Common.Implementations</Name>
       <Name>MediaBrowser.Common.Implementations</Name>

+ 6 - 2
MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs

@@ -1,6 +1,7 @@
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -23,16 +24,19 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks.Tasks
         /// The _logger
         /// The _logger
         /// </summary>
         /// </summary>
         private readonly ILogger _logger;
         private readonly ILogger _logger;
+        private readonly ILibraryManager _libraryManager;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="ChapterImagesTask" /> class.
         /// Initializes a new instance of the <see cref="ChapterImagesTask" /> class.
         /// </summary>
         /// </summary>
         /// <param name="kernel">The kernel.</param>
         /// <param name="kernel">The kernel.</param>
         /// <param name="logger">The logger.</param>
         /// <param name="logger">The logger.</param>
-        public ChapterImagesTask(Kernel kernel, ILogger logger)
+        /// <param name="libraryManager">The library manager.</param>
+        public ChapterImagesTask(Kernel kernel, ILogger logger, ILibraryManager libraryManager)
         {
         {
             _kernel = kernel;
             _kernel = kernel;
             _logger = logger;
             _logger = logger;
+            _libraryManager = libraryManager;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -55,7 +59,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks.Tasks
         /// <returns>Task.</returns>
         /// <returns>Task.</returns>
         public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
         public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
         {
         {
-            var videos = _kernel.RootFolder.RecursiveChildren.OfType<Video>().Where(v => v.Chapters != null).ToList();
+            var videos = _libraryManager.RootFolder.RecursiveChildren.OfType<Video>().Where(v => v.Chapters != null).ToList();
 
 
             var numComplete = 0;
             var numComplete = 0;
 
 

+ 7 - 4
MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/ImageCleanupTask.cs

@@ -2,6 +2,7 @@
 using MediaBrowser.Controller;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -25,16 +26,18 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks.Tasks
         /// The _logger
         /// The _logger
         /// </summary>
         /// </summary>
         private readonly ILogger _logger;
         private readonly ILogger _logger;
+        private readonly ILibraryManager _libraryManager;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="ImageCleanupTask" /> class.
         /// Initializes a new instance of the <see cref="ImageCleanupTask" /> class.
         /// </summary>
         /// </summary>
         /// <param name="kernel">The kernel.</param>
         /// <param name="kernel">The kernel.</param>
         /// <param name="logger">The logger.</param>
         /// <param name="logger">The logger.</param>
-        public ImageCleanupTask(Kernel kernel, ILogger logger)
+        public ImageCleanupTask(Kernel kernel, ILogger logger, ILibraryManager libraryManager)
         {
         {
             _kernel = kernel;
             _kernel = kernel;
             _logger = logger;
             _logger = logger;
+            _libraryManager = libraryManager;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -66,8 +69,8 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks.Tasks
                 .ToList();
                 .ToList();
 
 
             // Now gather all items
             // Now gather all items
-            var items = _kernel.RootFolder.RecursiveChildren.ToList();
-            items.Add(_kernel.RootFolder);
+            var items = _libraryManager.RootFolder.RecursiveChildren.ToList();
+            items.Add(_libraryManager.RootFolder);
 
 
             // Determine all possible image paths
             // Determine all possible image paths
             var pathsInUse = items.SelectMany(GetPathsInUse)
             var pathsInUse = items.SelectMany(GetPathsInUse)
@@ -115,7 +118,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks.Tasks
         /// <returns>Task.</returns>
         /// <returns>Task.</returns>
         private Task EnsureChapterImages(CancellationToken cancellationToken)
         private Task EnsureChapterImages(CancellationToken cancellationToken)
         {
         {
-            var videos = _kernel.RootFolder.RecursiveChildren.OfType<Video>().Where(v => v.Chapters != null).ToList();
+            var videos = _libraryManager.RootFolder.RecursiveChildren.OfType<Video>().Where(v => v.Chapters != null).ToList();
 
 
             var tasks = videos.Select(v => Task.Run(async () =>
             var tasks = videos.Select(v => Task.Run(async () =>
             {
             {

+ 1 - 0
MediaBrowser.Server.Implementations/packages.config

@@ -1,4 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
 <packages>
+  <package id="morelinq" version="1.0.15631-beta" targetFramework="net45" />
   <package id="System.Data.SQLite" version="1.0.84.0" targetFramework="net45" />
   <package id="System.Data.SQLite" version="1.0.84.0" targetFramework="net45" />
 </packages>
 </packages>

+ 12 - 14
MediaBrowser.ServerApplication/ApplicationHost.cs

@@ -1,14 +1,12 @@
-using BDInfo;
+using MediaBrowser.Api;
 using MediaBrowser.ClickOnce;
 using MediaBrowser.ClickOnce;
 using MediaBrowser.Common.Implementations;
 using MediaBrowser.Common.Implementations;
-using MediaBrowser.Common.Implementations.HttpClientManager;
 using MediaBrowser.Common.Implementations.HttpServer;
 using MediaBrowser.Common.Implementations.HttpServer;
 using MediaBrowser.Common.Implementations.Logging;
 using MediaBrowser.Common.Implementations.Logging;
 using MediaBrowser.Common.Implementations.NetworkManagement;
 using MediaBrowser.Common.Implementations.NetworkManagement;
 using MediaBrowser.Common.Implementations.ScheduledTasks;
 using MediaBrowser.Common.Implementations.ScheduledTasks;
 using MediaBrowser.Common.Implementations.Serialization;
 using MediaBrowser.Common.Implementations.Serialization;
 using MediaBrowser.Common.Implementations.ServerManager;
 using MediaBrowser.Common.Implementations.ServerManager;
-using MediaBrowser.Common.Implementations.Udp;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Kernel;
 using MediaBrowser.Common.Kernel;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
@@ -23,11 +21,12 @@ using MediaBrowser.Model.Serialization;
 using MediaBrowser.Model.System;
 using MediaBrowser.Model.System;
 using MediaBrowser.Model.Updates;
 using MediaBrowser.Model.Updates;
 using MediaBrowser.Server.Implementations;
 using MediaBrowser.Server.Implementations;
+using MediaBrowser.Server.Implementations.BdInfo;
 using MediaBrowser.Server.Implementations.Library;
 using MediaBrowser.Server.Implementations.Library;
 using MediaBrowser.ServerApplication.Implementations;
 using MediaBrowser.ServerApplication.Implementations;
+using MediaBrowser.WebDashboard.Api;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.Diagnostics;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Reflection;
 using System.Reflection;
@@ -120,7 +119,6 @@ namespace MediaBrowser.ServerApplication
 
 
             RegisterSingleInstance<IApplicationHost>(this);
             RegisterSingleInstance<IApplicationHost>(this);
 
 
-            RegisterSingleInstance<IUserManager>(new UserManager(Kernel, Logger));
 
 
             RegisterSingleInstance(ServerApplicationPaths);
             RegisterSingleInstance(ServerApplicationPaths);
             RegisterSingleInstance<IIsoManager>(new PismoIsoManager(Logger));
             RegisterSingleInstance<IIsoManager>(new PismoIsoManager(Logger));
@@ -129,6 +127,11 @@ namespace MediaBrowser.ServerApplication
             RegisterSingleInstance(_jsonSerializer);
             RegisterSingleInstance(_jsonSerializer);
             RegisterSingleInstance(_xmlSerializer);
             RegisterSingleInstance(_xmlSerializer);
             RegisterSingleInstance(ServerFactory.CreateServer(this, ProtobufSerializer, Logger, "Media Browser", "index.html"), false);
             RegisterSingleInstance(ServerFactory.CreateServer(this, ProtobufSerializer, Logger, "Media Browser", "index.html"), false);
+
+            var userManager = new UserManager(Kernel, Logger);
+            RegisterSingleInstance<IUserManager>(userManager);
+
+            RegisterSingleInstance<ILibraryManager>(new LibraryManager(Kernel, Logger, taskManager, userManager));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -186,16 +189,11 @@ namespace MediaBrowser.ServerApplication
                 yield return pluginAssembly;
                 yield return pluginAssembly;
             }
             }
 
 
-            var runningDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
-            var corePluginDirectory = Path.Combine(runningDirectory, "CorePlugins");
+            // Include composable parts in the Api assembly 
+            yield return typeof(ApiService).Assembly;
 
 
-            // This will prevent the .dll file from getting locked, and allow us to replace it when needed
-            foreach (var pluginAssembly in Directory
-                .EnumerateFiles(corePluginDirectory, "*.dll", SearchOption.TopDirectoryOnly)
-                .Select(LoadAssembly).Where(a => a != null))
-            {
-                yield return pluginAssembly;
-            }
+            // Include composable parts in the Dashboard assembly 
+            yield return typeof(DashboardInfo).Assembly;
 
 
             // Include composable parts in the Model assembly 
             // Include composable parts in the Model assembly 
             yield return typeof(SystemInfo).Assembly;
             yield return typeof(SystemInfo).Assembly;

+ 6 - 3
MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs

@@ -31,7 +31,8 @@ namespace MediaBrowser.ServerApplication
         private readonly ILogger _logger;
         private readonly ILogger _logger;
 
 
         private readonly IJsonSerializer _jsonSerializer;
         private readonly IJsonSerializer _jsonSerializer;
-        
+        private readonly ILibraryManager _libraryManager;
+  
         /// <summary>
         /// <summary>
         /// The current user
         /// The current user
         /// </summary>
         /// </summary>
@@ -39,7 +40,7 @@ namespace MediaBrowser.ServerApplication
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="LibraryExplorer" /> class.
         /// Initializes a new instance of the <see cref="LibraryExplorer" /> class.
         /// </summary>
         /// </summary>
-        public LibraryExplorer(IJsonSerializer jsonSerializer, ILogger logger, IApplicationHost appHost, IUserManager userManager)
+        public LibraryExplorer(IJsonSerializer jsonSerializer, ILogger logger, IApplicationHost appHost, IUserManager userManager, ILibraryManager libraryManager)
         {
         {
             _logger = logger;
             _logger = logger;
             _jsonSerializer = jsonSerializer;
             _jsonSerializer = jsonSerializer;
@@ -51,6 +52,8 @@ namespace MediaBrowser.ServerApplication
             ddlProfile.Items.Insert(0,new User {Name = "Physical"});
             ddlProfile.Items.Insert(0,new User {Name = "Physical"});
             ddlProfile.SelectedIndex = 0;
             ddlProfile.SelectedIndex = 0;
             ddlIndexBy.Visibility = ddlSortBy.Visibility = lblIndexBy.Visibility = lblSortBy.Visibility = Visibility.Hidden;
             ddlIndexBy.Visibility = ddlSortBy.Visibility = lblIndexBy.Visibility = lblSortBy.Visibility = Visibility.Hidden;
+
+            _libraryManager = libraryManager;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -77,7 +80,7 @@ namespace MediaBrowser.ServerApplication
             await Task.Run(() =>
             await Task.Run(() =>
                                {
                                {
                                    IEnumerable<BaseItem> children;
                                    IEnumerable<BaseItem> children;
-                                   children = CurrentUser.Name == "Physical" ? Kernel.Instance.RootFolder.Children.OrderBy(i => i.SortName) : Kernel.Instance.RootFolder.GetChildren(CurrentUser, sortBy: LocalizedStrings.Instance.GetString("NameDispPref"));
+                                   children = CurrentUser.Name == "Physical" ? _libraryManager.RootFolder.Children.OrderBy(i => i.SortName) : _libraryManager.RootFolder.GetChildren(CurrentUser, sortBy: LocalizedStrings.Instance.GetString("NameDispPref"));
 
 
                                    foreach (Folder folder in children)
                                    foreach (Folder folder in children)
                                    {
                                    {

+ 6 - 3
MediaBrowser.ServerApplication/MainWindow.xaml.cs

@@ -54,6 +54,8 @@ namespace MediaBrowser.ServerApplication
         /// The _log manager
         /// The _log manager
         /// </summary>
         /// </summary>
         private readonly ILogManager _logManager;
         private readonly ILogManager _logManager;
+
+        private readonly ILibraryManager _libraryManager;
         
         
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="MainWindow" /> class.
         /// Initializes a new instance of the <see cref="MainWindow" /> class.
@@ -62,7 +64,7 @@ namespace MediaBrowser.ServerApplication
         /// <param name="logger">The logger.</param>
         /// <param name="logger">The logger.</param>
         /// <param name="appHost">The app host.</param>
         /// <param name="appHost">The app host.</param>
         /// <exception cref="System.ArgumentNullException">logger</exception>
         /// <exception cref="System.ArgumentNullException">logger</exception>
-        public MainWindow(ILogManager logManager, IApplicationHost appHost)
+        public MainWindow(ILogManager logManager, IApplicationHost appHost, ILibraryManager libraryManager)
         {
         {
             if (logManager == null)
             if (logManager == null)
             {
             {
@@ -72,6 +74,7 @@ namespace MediaBrowser.ServerApplication
             _logger = logManager.GetLogger("MainWindow");
             _logger = logManager.GetLogger("MainWindow");
             _appHost = appHost;
             _appHost = appHost;
             _logManager = logManager;
             _logManager = logManager;
+            _libraryManager = libraryManager;
 
 
             InitializeComponent();
             InitializeComponent();
 
 
@@ -231,8 +234,8 @@ namespace MediaBrowser.ServerApplication
         /// <param name="e">The e.</param>
         /// <param name="e">The e.</param>
         void KernelReloadCompleted(object sender, EventArgs e)
         void KernelReloadCompleted(object sender, EventArgs e)
         {
         {
-            Kernel.Instance.LibraryManager.LibraryChanged -= Instance_LibraryChanged;
-            Kernel.Instance.LibraryManager.LibraryChanged += Instance_LibraryChanged;
+            _libraryManager.LibraryChanged -= Instance_LibraryChanged;
+            _libraryManager.LibraryChanged += Instance_LibraryChanged;
 
 
             if (_appHost.IsFirstRun)
             if (_appHost.IsFirstRun)
             {
             {

+ 7 - 9
MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj

@@ -254,9 +254,9 @@
     </None>
     </None>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\BDInfo\BDInfo.csproj">
-      <Project>{07b509c0-0c28-4f3f-8963-5263281f7e3d}</Project>
-      <Name>BDInfo</Name>
+    <ProjectReference Include="..\MediaBrowser.Api\MediaBrowser.Api.csproj">
+      <Project>{4fd51ac5-2c16-4308-a993-c3a84f3b4582}</Project>
+      <Name>MediaBrowser.Api</Name>
     </ProjectReference>
     </ProjectReference>
     <ProjectReference Include="..\MediaBrowser.ClickOnce\MediaBrowser.ClickOnce.csproj">
     <ProjectReference Include="..\MediaBrowser.ClickOnce\MediaBrowser.ClickOnce.csproj">
       <Project>{cc96bf3e-0bda-4809-bc4b-bb6d418f4a84}</Project>
       <Project>{cc96bf3e-0bda-4809-bc4b-bb6d418f4a84}</Project>
@@ -286,6 +286,10 @@
       <Project>{2e781478-814d-4a48-9d80-bff206441a65}</Project>
       <Project>{2e781478-814d-4a48-9d80-bff206441a65}</Project>
       <Name>MediaBrowser.Server.Implementations</Name>
       <Name>MediaBrowser.Server.Implementations</Name>
     </ProjectReference>
     </ProjectReference>
+    <ProjectReference Include="..\MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj">
+      <Project>{5624b7b5-b5a7-41d8-9f10-cc5611109619}</Project>
+      <Name>MediaBrowser.WebDashboard</Name>
+    </ProjectReference>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <Resource Include="Resources\Images\icon.ico" />
     <Resource Include="Resources\Images\icon.ico" />
@@ -364,12 +368,6 @@
     </BootstrapperPackage>
     </BootstrapperPackage>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
-    <Content Include="CorePlugins\MediaBrowser.Api.dll">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </Content>
-    <Content Include="CorePlugins\MediaBrowser.WebDashboard.dll">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </Content>
     <Content Include="x64\SQLite.Interop.dll">
     <Content Include="x64\SQLite.Interop.dll">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </Content>
     </Content>

+ 2 - 1
MediaBrowser.WebDashboard/Html/scripts/site.js

@@ -1099,7 +1099,8 @@ var Dashboard = {
             if (item.PrimaryImageTag) {
             if (item.PrimaryImageTag) {
                 data.icon = ApiClient.getImageUrl(item.Id, {
                 data.icon = ApiClient.getImageUrl(item.Id, {
                     width: 100,
                     width: 100,
-                    tag: item.PrimaryImageTag
+                    tag: item.PrimaryImageTag,
+                    type: "Primary"
                 });
                 });
             }
             }
 
 

+ 2 - 1
MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj

@@ -405,7 +405,8 @@
   </ItemGroup>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
   <PropertyGroup>
-    <PostBuildEvent>xcopy "$(TargetPath)" "$(SolutionDir)\MediaBrowser.ServerApplication\CorePlugins\" /y</PostBuildEvent>
+    <PostBuildEvent>
+    </PostBuildEvent>
   </PropertyGroup>
   </PropertyGroup>
   <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
   <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 

+ 1 - 1
Nuget/MediaBrowser.ApiClient.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
 <package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
     <metadata>
     <metadata>
         <id>MediaBrowser.ApiClient</id>
         <id>MediaBrowser.ApiClient</id>
-        <version>3.0.0.15-beta</version>
+        <version>3.0.0.17-beta</version>
         <title>MediaBrowser.ApiClient</title>
         <title>MediaBrowser.ApiClient</title>
         <authors>Media Browser Team</authors>
         <authors>Media Browser Team</authors>
         <owners>scottisafool,Luke</owners>
         <owners>scottisafool,Luke</owners>

+ 2 - 2
Nuget/MediaBrowser.Common.Internal.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
 <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
     <metadata>
     <metadata>
         <id>MediaBrowser.Common.Internal</id>
         <id>MediaBrowser.Common.Internal</id>
-        <version>3.0.15</version>
+        <version>3.0.17</version>
         <title />
         <title />
         <authors>Luke</authors>
         <authors>Luke</authors>
         <owners>Media Browser Team</owners>
         <owners>Media Browser Team</owners>
@@ -10,7 +10,7 @@
         <requireLicenseAcceptance>false</requireLicenseAcceptance>
         <requireLicenseAcceptance>false</requireLicenseAcceptance>
         <description>Contains common components shared by Media Browser Theatre and Media Browser Server. Not intended for plugin developer consumption.</description>
         <description>Contains common components shared by Media Browser Theatre and Media Browser Server. Not intended for plugin developer consumption.</description>
         <dependencies>
         <dependencies>
-            <dependency id="MediaBrowser.Common" version="3.0.15" />
+            <dependency id="MediaBrowser.Common" version="3.0.17" />
             <dependency id="NLog" version="2.0.0.2000" />
             <dependency id="NLog" version="2.0.0.2000" />
             <dependency id="ServiceStack" version="3.9.37" />
             <dependency id="ServiceStack" version="3.9.37" />
             <dependency id="ServiceStack.Api.Swagger" version="3.9.35" />
             <dependency id="ServiceStack.Api.Swagger" version="3.9.35" />

+ 1 - 1
Nuget/MediaBrowser.Common.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
 <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
     <metadata>
     <metadata>
         <id>MediaBrowser.Common</id>
         <id>MediaBrowser.Common</id>
-        <version>3.0.15</version>
+        <version>3.0.17</version>
         <title>MediaBrowser.Common</title>
         <title>MediaBrowser.Common</title>
         <authors>Media Browser Team</authors>
         <authors>Media Browser Team</authors>
         <owners />
         <owners />

+ 2 - 2
Nuget/MediaBrowser.Server.Core.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
 <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
     <metadata>
     <metadata>
         <id>MediaBrowser.Server.Core</id>
         <id>MediaBrowser.Server.Core</id>
-        <version>3.0.15</version>
+        <version>3.0.17</version>
         <title>Media Browser.Server.Core</title>
         <title>Media Browser.Server.Core</title>
         <authors>Media Browser Team</authors>
         <authors>Media Browser Team</authors>
         <owners />
         <owners />
@@ -10,7 +10,7 @@
         <requireLicenseAcceptance>false</requireLicenseAcceptance>
         <requireLicenseAcceptance>false</requireLicenseAcceptance>
         <description>Contains core components required to build plugins for Media Browser Server.</description>
         <description>Contains core components required to build plugins for Media Browser Server.</description>
         <dependencies>
         <dependencies>
-            <dependency id="MediaBrowser.Common" version="3.0.15" />
+            <dependency id="MediaBrowser.Common" version="3.0.17" />
         </dependencies>
         </dependencies>
     </metadata>
     </metadata>
     <files>
     <files>