ソースを参照

added more direct querying to folder

Luke Pulverenti 11 年 前
コミット
c643dd072e
25 ファイル変更143 行追加124 行削除
  1. 2 2
      MediaBrowser.Api/AlbumsService.cs
  2. 8 9
      MediaBrowser.Api/BaseApiService.cs
  3. 4 15
      MediaBrowser.Api/SearchService.cs
  4. 3 7
      MediaBrowser.Api/SimilarItemsHelper.cs
  5. 2 3
      MediaBrowser.Api/TvShowsService.cs
  6. 1 1
      MediaBrowser.Api/UserLibrary/ArtistsService.cs
  7. 2 19
      MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
  8. 1 1
      MediaBrowser.Api/UserLibrary/GameGenresService.cs
  9. 1 1
      MediaBrowser.Api/UserLibrary/GenresService.cs
  10. 1 1
      MediaBrowser.Api/UserLibrary/MusicGenresService.cs
  11. 1 1
      MediaBrowser.Api/UserLibrary/PersonsService.cs
  12. 1 1
      MediaBrowser.Api/UserLibrary/StudiosService.cs
  13. 1 3
      MediaBrowser.Api/UserLibrary/UserLibraryService.cs
  14. 1 1
      MediaBrowser.Api/UserLibrary/YearsService.cs
  15. 73 34
      MediaBrowser.Controller/Entities/Folder.cs
  16. 11 6
      MediaBrowser.Mono.userprefs
  17. 1 2
      MediaBrowser.Server.Implementations/Dto/DtoService.cs
  18. 10 4
      MediaBrowser.Server.Implementations/Library/LibraryManager.cs
  19. 1 1
      MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs
  20. 1 1
      MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs
  21. 1 1
      MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs
  22. 1 1
      MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs
  23. 1 1
      MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs
  24. 13 7
      MediaBrowser.Server.Mono/Program.cs
  25. 1 1
      MediaBrowser.ServerApplication/MainStartup.cs

+ 2 - 2
MediaBrowser.Api/AlbumsService.cs

@@ -75,7 +75,7 @@ namespace MediaBrowser.Api
             var album1 = (MusicAlbum)item1;
             var album2 = (MusicAlbum)item2;
 
-            var artists1 = album1.RecursiveChildren
+            var artists1 = album1.GetRecursiveChildren()
                 .OfType<Audio>()
                 .SelectMany(i =>
                 {
@@ -92,7 +92,7 @@ namespace MediaBrowser.Api
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .ToList();
 
-            var artists2 = album2.RecursiveChildren
+            var artists2 = album2.GetRecursiveChildren()
                 .OfType<Audio>()
                 .SelectMany(i =>
                 {

+ 8 - 9
MediaBrowser.Api/BaseApiService.cs

@@ -122,16 +122,16 @@ namespace MediaBrowser.Api
             return libraryManager.GetPerson(DeSlugPersonName(name, libraryManager));
         }
 
-        protected IEnumerable<BaseItem> GetAllLibraryItems(Guid? userId, IUserManager userManager, ILibraryManager libraryManager)
+        protected IList<BaseItem> GetAllLibraryItems(Guid? userId, IUserManager userManager, ILibraryManager libraryManager)
         {
             if (userId.HasValue)
             {
                 var user = userManager.GetUserById(userId.Value);
 
-                return userManager.GetUserById(userId.Value).RootFolder.GetRecursiveChildren(user);
+                return userManager.GetUserById(userId.Value).RootFolder.GetRecursiveChildren(user, null);
             }
 
-            return libraryManager.RootFolder.RecursiveChildren;
+            return libraryManager.RootFolder.GetRecursiveChildren();
         }
 
         /// <summary>
@@ -147,7 +147,7 @@ namespace MediaBrowser.Api
                 return name;
             }
 
-            return libraryManager.RootFolder.RecursiveChildren
+            return libraryManager.RootFolder.GetRecursiveChildren()
                 .OfType<Audio>()
                 .SelectMany(i =>
                 {
@@ -181,7 +181,7 @@ namespace MediaBrowser.Api
                 return name;
             }
 
-            return libraryManager.RootFolder.RecursiveChildren
+            return libraryManager.RootFolder.GetRecursiveChildren()
                 .SelectMany(i => i.Genres)
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .FirstOrDefault(i =>
@@ -200,8 +200,7 @@ namespace MediaBrowser.Api
                 return name;
             }
 
-            return libraryManager.RootFolder.RecursiveChildren
-                .OfType<Game>()
+            return libraryManager.RootFolder.GetRecursiveChildren(i => i is Game)
                 .SelectMany(i => i.Genres)
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .FirstOrDefault(i =>
@@ -223,7 +222,7 @@ namespace MediaBrowser.Api
                 return name;
             }
 
-            return libraryManager.RootFolder.RecursiveChildren
+            return libraryManager.RootFolder.GetRecursiveChildren()
                 .SelectMany(i => i.Studios)
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .FirstOrDefault(i =>
@@ -245,7 +244,7 @@ namespace MediaBrowser.Api
                 return name;
             }
 
-            return libraryManager.RootFolder.RecursiveChildren
+            return libraryManager.RootFolder.GetRecursiveChildren()
                 .SelectMany(i => i.People)
                 .Select(i => i.Name)
                 .Distinct(StringComparer.OrdinalIgnoreCase)

+ 4 - 15
MediaBrowser.Api/SearchService.cs

@@ -103,18 +103,7 @@ namespace MediaBrowser.Api
         /// <returns>Task{IEnumerable{SearchHintResult}}.</returns>
         private async Task<SearchHintResult> GetSearchHintsAsync(GetSearchHints request)
         {
-            IEnumerable<BaseItem> inputItems;
-
-            if (request.UserId.HasValue)
-            {
-                var user = _userManager.GetUserById(request.UserId.Value);
-
-                inputItems = user.RootFolder.GetRecursiveChildren(user);
-            }
-            else
-            {
-                inputItems = _libraryManager.RootFolder.RecursiveChildren;
-            }
+            var inputItems = GetAllLibraryItems(request.UserId, _userManager, _libraryManager);
 
             var results = await _searchEngine.GetSearchHints(inputItems, request.SearchTerm).ConfigureAwait(false);
 
@@ -180,21 +169,21 @@ namespace MediaBrowser.Api
             {
                 result.Series = season.Series.Name;
 
-                result.EpisodeCount = season.RecursiveChildren.OfType<Episode>().Count();
+                result.EpisodeCount = season.GetRecursiveChildren(i => i is Episode).Count;
             }
 
             var series = item as Series;
 
             if (series != null)
             {
-                result.EpisodeCount = series.RecursiveChildren.OfType<Episode>().Count();
+                result.EpisodeCount = series.GetRecursiveChildren(i => i is Episode).Count;
             }
 
             var album = item as MusicAlbum;
 
             if (album != null)
             {
-                var songs = album.RecursiveChildren.OfType<Audio>().ToList();
+                var songs = album.GetRecursiveChildren().OfType<Audio>().ToList();
 
                 result.SongCount = songs.Count;
                 

+ 3 - 7
MediaBrowser.Api/SimilarItemsHelper.cs

@@ -104,8 +104,8 @@ namespace MediaBrowser.Api
             var fields = request.GetItemFields().ToList();
 
             var inputItems = user == null
-                                 ? libraryManager.RootFolder.RecursiveChildren
-                                 : user.RootFolder.GetRecursiveChildren(user);
+                                 ? libraryManager.RootFolder.GetRecursiveChildren(i => i.Id != item.Id)
+                                 : user.RootFolder.GetRecursiveChildren(user, i => i.Id != item.Id);
 
             var items = GetSimilaritems(item, inputItems, includeInSearch, getSimilarityScore)
                 .ToList();
@@ -139,11 +139,7 @@ namespace MediaBrowser.Api
         {
             inputItems = inputItems.Where(includeInSearch);
 
-            // Avoid implicitly captured closure
-            var currentItem = item;
-
-            return inputItems.Where(i => i.Id != currentItem.Id)
-                .Select(i => new Tuple<BaseItem, int>(i, getSimilarityScore(item, i)))
+            return inputItems.Select(i => new Tuple<BaseItem, int>(i, getSimilarityScore(item, i)))
                 .Where(i => i.Item2 > 2)
                 .OrderByDescending(i => i.Item2)
                 .Select(i => i.Item1);

+ 2 - 3
MediaBrowser.Api/TvShowsService.cs

@@ -157,10 +157,9 @@ namespace MediaBrowser.Api
             var user = _userManager.GetUserById(request.UserId);
 
             var itemsList = user.RootFolder
-                .GetRecursiveChildren(user)
-                .OfType<Series>()
+                .GetRecursiveChildren(user, i => i is Series)
                 .AsParallel()
-                .Select(i => GetNextUp(i, user))
+                .Select(i => GetNextUp((Series)i, user))
                 .ToList();
 
             itemsList = itemsList

+ 1 - 1
MediaBrowser.Api/UserLibrary/ArtistsService.cs

@@ -98,7 +98,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>System.Object.</returns>
         public object Get(GetArtists request)
         {
-            var result = GetResult(request).Result;
+            var result = GetResult(request);
 
             return ToOptimizedResult(result);
         }

+ 2 - 19
MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs

@@ -53,7 +53,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// </summary>
         /// <param name="request">The request.</param>
         /// <returns>Task{ItemsResult}.</returns>
-        protected async Task<ItemsResult> GetResult(GetItemsByName request)
+        protected ItemsResult GetResult(GetItemsByName request)
         {
             User user = null;
             BaseItem item;
@@ -80,7 +80,7 @@ namespace MediaBrowser.Api.UserLibrary
                 }
                 else
                 {
-                    items = request.Recursive ? folder.RecursiveChildren : folder.Children;
+                    items = request.Recursive ? folder.GetRecursiveChildren() : folder.Children;
                 }
             }
             else
@@ -258,23 +258,6 @@ namespace MediaBrowser.Api.UserLibrary
 
             return dto;
         }
-
-        /// <summary>
-        /// Gets the items.
-        /// </summary>
-        /// <param name="userId">The user id.</param>
-        /// <returns>IEnumerable{BaseItem}.</returns>
-        protected IEnumerable<BaseItem> GetItems(Guid? userId)
-        {
-            if (userId.HasValue)
-            {
-                var user = UserManager.GetUserById(userId.Value);
-
-                return UserManager.GetUserById(userId.Value).RootFolder.GetRecursiveChildren(user);
-            }
-
-            return LibraryManager.RootFolder.RecursiveChildren;
-        }
     }
 
     /// <summary>

+ 1 - 1
MediaBrowser.Api/UserLibrary/GameGenresService.cs

@@ -89,7 +89,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>System.Object.</returns>
         public object Get(GetGameGenres request)
         {
-            var result = GetResult(request).Result;
+            var result = GetResult(request);
 
             return ToOptimizedResult(result);
         }

+ 1 - 1
MediaBrowser.Api/UserLibrary/GenresService.cs

@@ -93,7 +93,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>System.Object.</returns>
         public object Get(GetGenres request)
         {
-            var result = GetResult(request).Result;
+            var result = GetResult(request);
 
             return ToOptimizedResult(result);
         }

+ 1 - 1
MediaBrowser.Api/UserLibrary/MusicGenresService.cs

@@ -89,7 +89,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>System.Object.</returns>
         public object Get(GetMusicGenres request)
         {
-            var result = GetResult(request).Result;
+            var result = GetResult(request);
 
             return ToOptimizedResult(result);
         }

+ 1 - 1
MediaBrowser.Api/UserLibrary/PersonsService.cs

@@ -105,7 +105,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>System.Object.</returns>
         public object Get(GetPersons request)
         {
-            var result = GetResult(request).Result;
+            var result = GetResult(request);
 
             return ToOptimizedResult(result);
         }

+ 1 - 1
MediaBrowser.Api/UserLibrary/StudiosService.cs

@@ -94,7 +94,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>System.Object.</returns>
         public object Get(GetStudios request)
         {
-            var result = GetResult(request).Result;
+            var result = GetResult(request);
 
             return ToOptimizedResult(result);
         }

+ 1 - 3
MediaBrowser.Api/UserLibrary/UserLibraryService.cs

@@ -451,9 +451,7 @@ namespace MediaBrowser.Api.UserLibrary
             if (series != null)
             {
                 var dtos = series
-                    .RecursiveChildren
-                    .OfType<Episode>()
-                    .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
+                    .GetRecursiveChildren(i => i is Episode && i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
                     .OrderBy(i =>
                     {
                         if (i.PremiereDate.HasValue)

+ 1 - 1
MediaBrowser.Api/UserLibrary/YearsService.cs

@@ -99,7 +99,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>System.Object.</returns>
         public object Get(GetYears request)
         {
-            var result = GetResult(request).Result;
+            var result = GetResult(request);
 
             return ToOptimizedResult(result);
         }

+ 73 - 34
MediaBrowser.Controller/Entities/Folder.cs

@@ -552,23 +552,7 @@ namespace MediaBrowser.Controller.Entities
         [IgnoreDataMember]
         public IEnumerable<BaseItem> RecursiveChildren
         {
-            get
-            {
-                foreach (var item in Children)
-                {
-                    yield return item;
-
-                    if (item.IsFolder)
-                    {
-                        var subFolder = (Folder)item;
-
-                        foreach (var subitem in subFolder.RecursiveChildren)
-                        {
-                            yield return subitem;
-                        }
-                    }
-                }
-            }
+            get { return GetRecursiveChildren(); }
         }
 
         private List<BaseItem> LoadChildrenInternal()
@@ -686,17 +670,12 @@ namespace MediaBrowser.Controller.Entities
             var currentChildren = ActualChildren.ToDictionary(i => i.Id);
 
             //create a list for our validated children
-            var validChildren = new ConcurrentBag<Tuple<BaseItem, bool>>();
-            var newItems = new ConcurrentBag<BaseItem>();
+            var validChildren = new List<Tuple<BaseItem, bool>>();
+            var newItems = new List<BaseItem>();
 
             cancellationToken.ThrowIfCancellationRequested();
 
-            var options = new ParallelOptions
-            {
-                MaxDegreeOfParallelism = 10
-            };
-
-            Parallel.ForEach(nonCachedChildren, options, child =>
+            foreach (var child in nonCachedChildren)
             {
                 BaseItem currentChild;
 
@@ -725,10 +704,10 @@ namespace MediaBrowser.Controller.Entities
 
                     validChildren.Add(new Tuple<BaseItem, bool>(child, true));
                 }
-            });
+            }
 
             // If any items were added or removed....
-            if (!newItems.IsEmpty || currentChildren.Count != validChildren.Count)
+            if (newItems.Count > 0 || currentChildren.Count != validChildren.Count)
             {
                 var newChildren = validChildren.Select(c => c.Item1).ToList();
 
@@ -793,9 +772,9 @@ namespace MediaBrowser.Controller.Entities
         /// <param name="recursive">if set to <c>true</c> [recursive].</param>
         /// <param name="forceRefreshMetadata">if set to <c>true</c> [force refresh metadata].</param>
         /// <returns>Task.</returns>
-        private async Task RefreshChildren(IEnumerable<Tuple<BaseItem, bool>> children, IProgress<double> progress, CancellationToken cancellationToken, bool? recursive, bool forceRefreshMetadata = false)
+        private async Task RefreshChildren(IList<Tuple<BaseItem, bool>> children, IProgress<double> progress, CancellationToken cancellationToken, bool? recursive, bool forceRefreshMetadata = false)
         {
-            var list = children.ToList();
+            var list = children;
 
             var percentages = new Dictionary<Guid, double>(list.Count);
 
@@ -994,7 +973,7 @@ namespace MediaBrowser.Controller.Entities
         /// <param name="recursive">if set to <c>true</c> [recursive].</param>
         /// <param name="filter">The filter.</param>
         /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
-        private bool AddChildrenToList(User user, bool includeLinkedChildren, List<BaseItem> list, bool recursive, Func<BaseItem,bool> filter)
+        private bool AddChildrenToList(User user, bool includeLinkedChildren, List<BaseItem> list, bool recursive, Func<BaseItem, bool> filter)
         {
             var hasLinkedChildren = false;
 
@@ -1030,7 +1009,7 @@ namespace MediaBrowser.Controller.Entities
                     {
                         continue;
                     }
-                    
+
                     hasLinkedChildren = true;
 
                     if (child.IsVisible(user))
@@ -1056,7 +1035,15 @@ namespace MediaBrowser.Controller.Entities
             return GetRecursiveChildren(user, null, true);
         }
 
-        public IEnumerable<BaseItem> GetRecursiveChildren(User user, Func<BaseItem,bool> filter, bool includeLinkedChildren = true)
+        /// <summary>
+        /// Gets the recursive children.
+        /// </summary>
+        /// <param name="user">The user.</param>
+        /// <param name="filter">The filter.</param>
+        /// <param name="includeLinkedChildren">if set to <c>true</c> [include linked children].</param>
+        /// <returns>IList{BaseItem}.</returns>
+        /// <exception cref="System.ArgumentNullException"></exception>
+        public IList<BaseItem> GetRecursiveChildren(User user, Func<BaseItem, bool> filter, bool includeLinkedChildren = true)
         {
             if (user == null)
             {
@@ -1066,7 +1053,7 @@ namespace MediaBrowser.Controller.Entities
             var initialCount = _lastRecursiveCount == 0 ? _children.Count : _lastRecursiveCount;
             var list = new List<BaseItem>(initialCount);
 
-            var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, true, null);
+            var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, true, filter);
 
             _lastRecursiveCount = list.Count;
 
@@ -1077,7 +1064,59 @@ namespace MediaBrowser.Controller.Entities
 
             return list;
         }
-        
+
+        /// <summary>
+        /// Gets the recursive children.
+        /// </summary>
+        /// <returns>IList{BaseItem}.</returns>
+        public IList<BaseItem> GetRecursiveChildren()
+        {
+            return GetRecursiveChildren(null);
+        }
+
+        /// <summary>
+        /// Gets the recursive children.
+        /// </summary>
+        /// <param name="filter">The filter.</param>
+        /// <returns>IEnumerable{BaseItem}.</returns>
+        public IList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter)
+        {
+            var initialCount = _lastRecursiveCount == 0 ? _children.Count : _lastRecursiveCount;
+            var list = new List<BaseItem>(initialCount);
+
+            AddChildrenToList(list, true, filter);
+
+            return list;
+        }
+
+        /// <summary>
+        /// Adds the children to list.
+        /// </summary>
+        /// <param name="list">The list.</param>
+        /// <param name="recursive">if set to <c>true</c> [recursive].</param>
+        /// <param name="filter">The filter.</param>
+        private void AddChildrenToList(List<BaseItem> list, bool recursive, Func<BaseItem, bool> filter)
+        {
+            foreach (var child in Children)
+            {
+                if (filter == null || filter(child))
+                {
+                    list.Add(child);
+                }
+
+                if (recursive)
+                {
+                    var folder = child as Folder;
+
+                    if (folder != null)
+                    {
+                        folder.AddChildrenToList(list, true, filter);
+                    }
+                }
+            }
+        }
+
+
         /// <summary>
         /// Gets the linked children.
         /// </summary>

+ 11 - 6
MediaBrowser.Mono.userprefs

@@ -2,15 +2,20 @@
   <MonoDevelop.Ide.Workspace ActiveConfiguration="Debug|x86" />
   <MonoDevelop.Ide.Workbench ActiveDocument="d:\Development\MediaBrowser\MediaBrowser.ServerApplication\ApplicationHost.cs">
     <Files>
-      <File FileName="d:\Development\MediaBrowser\MediaBrowser.ServerApplication\ApplicationHost.cs" Line="442" Column="10" />
-      <File FileName="MediaBrowser.Server.Mono\Native\ServerAuthorization.cs" Line="1" Column="1" />
-      <File FileName="MediaBrowser.Server.Mono\Native\Autorun.cs" Line="1" Column="1" />
-      <File FileName="MediaBrowser.Server.Mono\Native\Assemblies.cs" Line="1" Column="1" />
-      <File FileName="MediaBrowser.Server.Mono\Program.cs" Line="1" Column="1" />
+      <File FileName="d:\Development\MediaBrowser\MediaBrowser.ServerApplication\ApplicationHost.cs" Line="506" Column="29" />
+      <File FileName="MediaBrowser.Server.Mono\Program.cs" Line="192" Column="1" />
+      <File FileName="MediaBrowser.Server.Mono\Native\NativeApp.cs" Line="24" Column="1" />
+      <File FileName="d:\Development\MediaBrowser\MediaBrowser.Common.Implementations\Logging\NLogger.cs" Line="72" Column="1" />
+      <File FileName="d:\Development\MediaBrowser\MediaBrowser.Common.Implementations\BaseApplicationHost.cs" Line="530" Column="1" />
     </Files>
   </MonoDevelop.Ide.Workbench>
   <MonoDevelop.Ide.DebuggingService.Breakpoints>
-    <BreakpointStore />
+    <BreakpointStore>
+      <Breakpoint file="D:\Development\MediaBrowser\MediaBrowser.Server.Mono\Program.cs" line="177" column="1" />
+      <Breakpoint file="D:\Development\MediaBrowser\MediaBrowser.Server.Mono\Program.cs" line="189" column="1" />
+      <Breakpoint file="D:\Development\MediaBrowser\MediaBrowser.Server.Mono\Native\NativeApp.cs" line="23" column="1" />
+      <Breakpoint file="D:\Development\MediaBrowser\MediaBrowser.Server.Mono\Native\NativeApp.cs" line="15" column="1" />
+    </BreakpointStore>
   </MonoDevelop.Ide.DebuggingService.Breakpoints>
   <MonoDevelop.Ide.DebuggingService.PinnedWatches />
 </Properties>

+ 1 - 2
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -354,8 +354,7 @@ namespace MediaBrowser.Server.Implementations.Dto
             if (!string.IsNullOrEmpty(item.Album))
             {
                 var parentAlbum = _libraryManager.RootFolder
-                    .RecursiveChildren
-                    .OfType<MusicAlbum>()
+                    .GetRecursiveChildren(i => i is MusicAlbum)
                     .FirstOrDefault(i => string.Equals(i.Name, item.Album, StringComparison.OrdinalIgnoreCase));
 
                 if (parentAlbum != null)

+ 10 - 4
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -337,7 +337,7 @@ namespace MediaBrowser.Server.Implementations.Library
         /// <returns>ConcurrentDictionary{GuidBaseItem}.</returns>
         private ConcurrentDictionary<Guid, BaseItem> CreateLibraryItemsCache()
         {
-            var items = RootFolder.RecursiveChildren.ToList();
+            var items = RootFolder.GetRecursiveChildren();
 
             items.Add(RootFolder);
 
@@ -347,7 +347,10 @@ namespace MediaBrowser.Server.Implementations.Library
                 .Distinct()
                 .ToList();
 
-            items.AddRange(userRootFolders);
+            foreach (var folder in userRootFolders)
+            {
+                items.Add(folder);
+            }
 
             // Get all user collection folders
             // Skip BasePluginFolders because we already got them from RootFolder.RecursiveChildren
@@ -355,7 +358,10 @@ namespace MediaBrowser.Server.Implementations.Library
                             .Where(i => !(i is BasePluginFolder))
                             .ToList();
 
-            items.AddRange(userFolders);
+            foreach (var folder in userFolders)
+            {
+                items.Add(folder);
+            }
 
             var dictionary = new ConcurrentDictionary<Guid, BaseItem>();
 
@@ -770,7 +776,7 @@ namespace MediaBrowser.Server.Implementations.Library
         /// <returns>Task.</returns>
         public async Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress)
         {
-            var people = RootFolder.RecursiveChildren
+            var people = RootFolder.GetRecursiveChildren()
                 .SelectMany(c => c.People)
                 .DistinctBy(p => p.Name, StringComparer.OrdinalIgnoreCase)
                 .ToList();

+ 1 - 1
MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs

@@ -57,7 +57,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// <returns>Task.</returns>
         public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
-            var allItems = _libraryManager.RootFolder.RecursiveChildren.ToList();
+            var allItems = _libraryManager.RootFolder.GetRecursiveChildren();
 
             var allMusicArtists = allItems.OfType<MusicArtist>().ToList();
             var allSongs = allItems.OfType<Audio>().ToList();

+ 1 - 1
MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs

@@ -43,7 +43,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
             var userLibraries = _userManager.Users
-                .Select(i => new Tuple<Guid, List<BaseItem>>(i.Id, i.RootFolder.GetRecursiveChildren(i).Where(m => !(m is IHasMusicGenres) && !(m is Game)).ToList()))
+                .Select(i => new Tuple<Guid, IList<BaseItem>>(i.Id, i.RootFolder.GetRecursiveChildren(i, m => !(m is IHasMusicGenres) && !(m is Game))))
                 .ToList();
 
             var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>>(StringComparer.OrdinalIgnoreCase);

+ 1 - 1
MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs

@@ -43,7 +43,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
             var userLibraries = _userManager.Users
-                .Select(i => new Tuple<Guid, List<BaseItem>>(i.Id, i.RootFolder.GetRecursiveChildren(i).Where(m => m is IHasMusicGenres).ToList()))
+                .Select(i => new Tuple<Guid, IList<BaseItem>>(i.Id, i.RootFolder.GetRecursiveChildren(i, m => m is IHasMusicGenres)))
                 .ToList();
 
             var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>>(StringComparer.OrdinalIgnoreCase);

+ 1 - 1
MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs

@@ -49,7 +49,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         private void RunInternal(IProgress<double> progress, CancellationToken cancellationToken)
         {
             var userLibraries = _userManager.Users
-                .Select(i => new Tuple<Guid, List<BaseItem>>(i.Id, i.RootFolder.GetRecursiveChildren(i).ToList()))
+                .Select(i => new Tuple<Guid, IList<BaseItem>>(i.Id, i.RootFolder.GetRecursiveChildren(i, null)))
                 .ToList();
 
             var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>>(StringComparer.OrdinalIgnoreCase);

+ 1 - 1
MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs

@@ -42,7 +42,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
             var userLibraries = _userManager.Users
-                .Select(i => new Tuple<Guid, List<BaseItem>>(i.Id, i.RootFolder.GetRecursiveChildren(i).ToList()))
+                .Select(i => new Tuple<Guid, IList<BaseItem>>(i.Id, i.RootFolder.GetRecursiveChildren(i, null)))
                 .ToList();
 
             var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>>(StringComparer.OrdinalIgnoreCase);

+ 13 - 7
MediaBrowser.Server.Mono/Program.cs

@@ -23,6 +23,8 @@ namespace MediaBrowser.Server.Mono
 
 		private static ILogger _logger;
 
+		private static MainWindow _mainWindow;
+
 		public static void Main (string[] args)
 		{
 			Application.Init ();
@@ -42,11 +44,11 @@ namespace MediaBrowser.Server.Mono
 
 			var runningPath = Process.GetCurrentProcess().MainModule.FileName.Replace(Path.DirectorySeparatorChar.ToString(), string.Empty);
 
-			_singleInstanceMutex = new Mutex(true, @"Local\" + runningPath, out createdNew);
-
+			//_singleInstanceMutex = new Mutex(true, @"Local\" + runningPath, out createdNew);
+			createdNew = true;
 			if (!createdNew)
 			{
-				_singleInstanceMutex = null;
+				//_singleInstanceMutex = null;
 				logger.Info("Shutting down because another instance of Media Browser Server is already running.");
 				return;
 			}
@@ -65,7 +67,7 @@ namespace MediaBrowser.Server.Mono
 			{
 				logger.Info("Shutting down");
 
-				ReleaseMutex(logger);
+				//ReleaseMutex(logger);
 
 				_appHost.Dispose();
 			}
@@ -91,9 +93,9 @@ namespace MediaBrowser.Server.Mono
 			Task.WaitAll (task);
 
 			// TODO: Hide splash here
-			MainWindow win = new MainWindow ();
+			_mainWindow = new MainWindow ();
 
-			win.Show ();
+			_mainWindow.Show ();
 
 			Application.Run ();
 		}
@@ -172,16 +174,20 @@ namespace MediaBrowser.Server.Mono
 
 		public static void Shutdown()
 		{
+			_mainWindow.Hide ();
+			_mainWindow.Dispose ();
 			Application.Quit ();
 		}
 
 		public static void Restart()
 		{
 			// Second instance will start first, so release the mutex and dispose the http server ahead of time
-			ReleaseMutex (_logger);
+			//ReleaseMutex (_logger);
 
 			_appHost.Dispose();
 
+			_mainWindow.Hide ();
+			_mainWindow.Dispose ();
 			Application.Quit ();
 		}
 	}

+ 1 - 1
MediaBrowser.ServerApplication/MainStartup.cs

@@ -314,7 +314,7 @@ namespace MediaBrowser.ServerApplication
         {
             var exception = (Exception)e.ExceptionObject;
 
-            _logger.ErrorException("UnhandledException", ex);
+            _logger.ErrorException("UnhandledException", exception);
 
             if (_backgroundService == null)
             {