Browse Source

calculate item by name counts on the fly

Luke Pulverenti 11 năm trước cách đây
mục cha
commit
d494944767
49 tập tin đã thay đổi với 517 bổ sung1196 xóa
  1. 4 1
      MediaBrowser.Api/BaseApiService.cs
  2. 4 2
      MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs
  3. 39 42
      MediaBrowser.Api/Playback/BaseStreamingService.cs
  4. 4 2
      MediaBrowser.Api/SearchService.cs
  5. 6 8
      MediaBrowser.Api/UserLibrary/ArtistsService.cs
  6. 19 19
      MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
  7. 2 7
      MediaBrowser.Api/UserLibrary/GameGenresService.cs
  8. 2 7
      MediaBrowser.Api/UserLibrary/GenresService.cs
  9. 2 7
      MediaBrowser.Api/UserLibrary/MusicGenresService.cs
  10. 2 7
      MediaBrowser.Api/UserLibrary/PersonsService.cs
  11. 2 7
      MediaBrowser.Api/UserLibrary/StudiosService.cs
  12. 2 17
      MediaBrowser.Api/UserLibrary/YearsService.cs
  13. 67 0
      MediaBrowser.Controller/Channels/ChannelItemInfo.cs
  14. 57 0
      MediaBrowser.Controller/Channels/IChannel.cs
  15. 12 0
      MediaBrowser.Controller/Channels/IChannelManager.cs
  16. 21 0
      MediaBrowser.Controller/Dto/IDtoService.cs
  17. 18 0
      MediaBrowser.Controller/Entities/Audio/Audio.cs
  18. 5 6
      MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
  19. 7 11
      MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
  20. 7 10
      MediaBrowser.Controller/Entities/GameGenre.cs
  21. 8 10
      MediaBrowser.Controller/Entities/Genre.cs
  22. 7 31
      MediaBrowser.Controller/Entities/IItemByName.cs
  23. 7 10
      MediaBrowser.Controller/Entities/Person.cs
  24. 7 11
      MediaBrowser.Controller/Entities/Studio.cs
  25. 17 12
      MediaBrowser.Controller/Entities/Year.cs
  26. 0 13
      MediaBrowser.Controller/Library/ILibraryManager.cs
  27. 0 7
      MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
  28. 5 10
      MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
  29. 3 0
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  30. 0 7
      MediaBrowser.Model/Querying/ItemSortBy.cs
  31. 36 26
      MediaBrowser.Server.Implementations/Dto/DtoService.cs
  32. 6 3
      MediaBrowser.Server.Implementations/Library/LibraryManager.cs
  33. 3 1
      MediaBrowser.Server.Implementations/Library/SearchEngine.cs
  34. 2 43
      MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs
  35. 10 52
      MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs
  36. 10 52
      MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs
  37. 12 61
      MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs
  38. 6 97
      MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs
  39. 4 2
      MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs
  40. 11 54
      MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs
  41. 81 37
      MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
  42. 0 7
      MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
  43. 0 71
      MediaBrowser.Server.Implementations/Sorting/AlbumCountComparer.cs
  44. 0 71
      MediaBrowser.Server.Implementations/Sorting/EpisodeCountComparer.cs
  45. 0 71
      MediaBrowser.Server.Implementations/Sorting/MovieCountComparer.cs
  46. 0 71
      MediaBrowser.Server.Implementations/Sorting/MusicVideoCountComparer.cs
  47. 0 71
      MediaBrowser.Server.Implementations/Sorting/SeriesCountComparer.cs
  48. 0 71
      MediaBrowser.Server.Implementations/Sorting/SongCountComparer.cs
  49. 0 71
      MediaBrowser.Server.Implementations/Sorting/TrailerCountComparer.cs

+ 4 - 1
MediaBrowser.Api/BaseApiService.cs

@@ -164,7 +164,10 @@ namespace MediaBrowser.Api
                 return name;
             }
 
-            return libraryManager.GetAllArtists()
+            return libraryManager.RootFolder.RecursiveChildren
+                .OfType<Audio>()
+                .SelectMany(i => i.AllArtists)
+                .Distinct(StringComparer.OrdinalIgnoreCase)
                 .FirstOrDefault(i =>
                 {
                     i = _dashReplaceChars.Aggregate(i, (current, c) => current.Replace(c, SlugChar));

+ 4 - 2
MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs

@@ -194,8 +194,10 @@ namespace MediaBrowser.Api.DefaultTheme
                 .Select(i => _dtoService.GetBaseItemDto(i, fields, user))
                 .ToList();
 
-            var artists = _libraryManager.GetAllArtists(allItems)
-            .Randomize()
+            var artists = allItems.OfType<Audio>()
+                .SelectMany(i => i.AllArtists)
+                .Distinct(StringComparer.OrdinalIgnoreCase)
+                .Randomize()
             .Select(i =>
             {
                 try

+ 39 - 42
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -491,16 +491,16 @@ namespace MediaBrowser.Api.Playback
 
                 return string.Format("{4} -vf \"{0}scale=trunc({1}/2)*2:trunc({2}/2)*2{3}\"", yadifParam, widthParam, heightParam, assSubtitleParam, copyTsParam);
             }
-            
-              // If Max dimensions were supplied
-              //this makes my brain hurt. For width selects lowest even number between input width and width req size and selects lowest even number from in width*display aspect and requested size
-             if (request.MaxWidth.HasValue && request.MaxHeight.HasValue)
-             {
-                 var MaxwidthParam = request.MaxWidth.Value.ToString(UsCulture);
-                 var MaxheightParam = request.MaxHeight.Value.ToString(UsCulture);
- 
-                 return string.Format("{4} -vf \"{0}scale=trunc(min(iw\\,{1})/2)*2:trunc(min((iw/dar)\\,{2})/2)*2{3}\"", yadifParam, MaxwidthParam, MaxheightParam, assSubtitleParam, copyTsParam);
-             }
+
+            // If Max dimensions were supplied
+            //this makes my brain hurt. For width selects lowest even number between input width and width req size and selects lowest even number from in width*display aspect and requested size
+            if (request.MaxWidth.HasValue && request.MaxHeight.HasValue)
+            {
+                var MaxwidthParam = request.MaxWidth.Value.ToString(UsCulture);
+                var MaxheightParam = request.MaxHeight.Value.ToString(UsCulture);
+
+                return string.Format("{4} -vf \"{0}scale=trunc(min(iw\\,{1})/2)*2:trunc(min((iw/dar)\\,{2})/2)*2{3}\"", yadifParam, MaxwidthParam, MaxheightParam, assSubtitleParam, copyTsParam);
+            }
 
             var isH264Output = outputVideoCodec.Equals("libx264", StringComparison.OrdinalIgnoreCase);
 
@@ -603,7 +603,7 @@ namespace MediaBrowser.Api.Playback
         private string GetExtractedAssPath(StreamState state, bool performConversion)
         {
             var path = EncodingManager.GetSubtitleCachePath(state.MediaPath, state.SubtitleStream.Index, ".ass");
-            
+
             if (performConversion)
             {
                 InputType type;
@@ -985,20 +985,15 @@ namespace MediaBrowser.Api.Playback
 
             if (state.VideoStream != null)
             {
-                var isUpscaling = false;
-
-                if (state.VideoRequest.Height.HasValue && state.VideoStream.Height.HasValue &&
-                    state.VideoRequest.Height.Value > state.VideoStream.Height.Value)
-                {
-                    isUpscaling = true;
-                }
+                var isUpscaling = state.VideoRequest.Height.HasValue && state.VideoStream.Height.HasValue &&
+                                   state.VideoRequest.Height.Value > state.VideoStream.Height.Value;
 
                 if (state.VideoRequest.Width.HasValue && state.VideoStream.Width.HasValue &&
                     state.VideoRequest.Width.Value > state.VideoStream.Width.Value)
                 {
                     isUpscaling = true;
                 }
-                
+
                 // Don't allow bitrate increases unless upscaling
                 if (!isUpscaling)
                 {
@@ -1307,37 +1302,34 @@ namespace MediaBrowser.Api.Playback
                 state.IsInputVideo = string.Equals(recording.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);
                 state.PlayableStreamFileNames = new List<string>();
 
-                if (!string.IsNullOrEmpty(recording.RecordingInfo.Path) && File.Exists(recording.RecordingInfo.Path))
-                {
-                    state.MediaPath = recording.RecordingInfo.Path;
-                    state.IsRemote = false;
-                }
-                else if (!string.IsNullOrEmpty(recording.RecordingInfo.Url))
-                {
-                    state.MediaPath = recording.RecordingInfo.Url;
-                    state.IsRemote = true;
-                }
-                else
+                var path = recording.RecordingInfo.Path;
+                var mediaUrl = recording.RecordingInfo.Url;
+
+                if (string.IsNullOrWhiteSpace(path) && string.IsNullOrWhiteSpace(mediaUrl))
                 {
                     var streamInfo = await LiveTvManager.GetRecordingStream(request.Id, cancellationToken).ConfigureAwait(false);
 
                     state.LiveTvStreamId = streamInfo.Id;
 
-                    if (!string.IsNullOrEmpty(streamInfo.Path) && File.Exists(streamInfo.Path))
-                    {
-                        state.MediaPath = streamInfo.Path;
-                        state.IsRemote = false;
-                    }
-                    else if (!string.IsNullOrEmpty(streamInfo.Url))
-                    {
-                        state.MediaPath = streamInfo.Url;
-                        state.IsRemote = true;
-                    }
+                    path = streamInfo.Path;
+                    mediaUrl = streamInfo.Url;
+                }
+
+                if (!string.IsNullOrEmpty(path) && File.Exists(path))
+                {
+                    state.MediaPath = path;
+                    state.IsRemote = false;
+
+                    state.SendInputOverStandardInput = recording.RecordingInfo.Status == RecordingStatus.InProgress;
+                }
+                else if (!string.IsNullOrEmpty(mediaUrl))
+                {
+                    state.MediaPath = mediaUrl;
+                    state.IsRemote = true;
                 }
 
                 //state.RunTimeTicks = recording.RunTimeTicks;
                 state.ReadInputAtNativeFramerate = recording.RecordingInfo.Status == RecordingStatus.InProgress;
-                state.SendInputOverStandardInput = recording.RecordingInfo.Status == RecordingStatus.InProgress;
                 state.AudioSync = "1000";
                 state.DeInterlace = true;
             }
@@ -1357,6 +1349,7 @@ namespace MediaBrowser.Api.Playback
                 {
                     state.MediaPath = streamInfo.Path;
                     state.IsRemote = false;
+                    state.SendInputOverStandardInput = true;
                 }
                 else if (!string.IsNullOrEmpty(streamInfo.Url))
                 {
@@ -1364,7 +1357,6 @@ namespace MediaBrowser.Api.Playback
                     state.IsRemote = true;
                 }
 
-                state.SendInputOverStandardInput = true;
                 state.ReadInputAtNativeFramerate = true;
                 state.AudioSync = "1000";
                 state.DeInterlace = true;
@@ -1409,6 +1401,11 @@ namespace MediaBrowser.Api.Playback
                 state.SubtitleStream = GetMediaStream(mediaStreams, videoRequest.SubtitleStreamIndex, MediaStreamType.Subtitle, false);
                 state.AudioStream = GetMediaStream(mediaStreams, videoRequest.AudioStreamIndex, MediaStreamType.Audio);
 
+                if (state.VideoStream != null && state.VideoStream.IsInterlaced)
+                {
+                    state.DeInterlace = true;
+                }
+
                 EnforceResolutionLimit(state, videoRequest);
             }
             else

+ 4 - 2
MediaBrowser.Api/SearchService.cs

@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Drawing;
+using System;
+using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
@@ -210,7 +211,8 @@ namespace MediaBrowser.Api
 
                 result.SongCount = songs.Count;
 
-                result.Artists = _libraryManager.GetAllArtists(songs)
+                result.Artists = songs.SelectMany(i => i.AllArtists)
+                    .Distinct(StringComparer.OrdinalIgnoreCase)
                     .ToArray();
 
                 result.AlbumArtist = songs.Select(i => i.AlbumArtist).FirstOrDefault(i => !string.IsNullOrEmpty(i));

+ 6 - 8
MediaBrowser.Api/UserLibrary/ArtistsService.cs

@@ -85,10 +85,10 @@ namespace MediaBrowser.Api.UserLibrary
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
 
-                return DtoService.GetBaseItemDto(item, fields.ToList(), user);
+                return DtoService.GetItemByNameDto(item, fields.ToList(), user);
             }
 
-            return DtoService.GetBaseItemDto(item, fields.ToList());
+            return DtoService.GetItemByNameDto(item, fields.ToList());
         }
 
         /// <summary>
@@ -111,7 +111,10 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
         protected override IEnumerable<MusicArtist> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
         {
-            return LibraryManager.GetAllArtists(items)
+            return items
+                .OfType<Audio>()
+                .SelectMany(i => i.AllArtists)
+                .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Select(name =>
                 {
                     try
@@ -126,10 +129,5 @@ namespace MediaBrowser.Api.UserLibrary
 
                 }).Where(i => i != null);
         }
-
-        protected override IEnumerable<BaseItem> GetLibraryItems(MusicArtist item, IEnumerable<BaseItem> libraryItems)
-        {
-            return libraryItems.OfType<IHasArtist>().Where(i => i.HasArtist(item.Name)).Cast<BaseItem>();
-        }
     }
 }

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

@@ -56,15 +56,21 @@ namespace MediaBrowser.Api.UserLibrary
         {
             User user = null;
             BaseItem item;
+            List<BaseItem> libraryItems;
 
             if (request.UserId.HasValue)
             {
                 user = UserManager.GetUserById(request.UserId.Value);
                 item = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : DtoService.GetItemByDtoId(request.ParentId, user.Id);
+
+                libraryItems = user.RootFolder.GetRecursiveChildren(user).ToList();
+
             }
             else
             {
                 item = string.IsNullOrEmpty(request.ParentId) ? LibraryManager.RootFolder : DtoService.GetItemByDtoId(request.ParentId);
+
+                libraryItems = LibraryManager.RootFolder.RecursiveChildren.ToList();
             }
 
             IEnumerable<BaseItem> items;
@@ -93,7 +99,7 @@ namespace MediaBrowser.Api.UserLibrary
 
             var filteredItems = FilterItems(request, extractedItems, user);
 
-            filteredItems = FilterByLibraryItems(request, filteredItems, user);
+            filteredItems = FilterByLibraryItems(request, filteredItems, user, libraryItems);
 
             filteredItems = ItemsService.ApplySortOrder(request, filteredItems, user, LibraryManager).Cast<TItemType>();
 
@@ -122,45 +128,39 @@ namespace MediaBrowser.Api.UserLibrary
 
             var fields = request.GetItemFields().ToList();
 
-            var dtos = ibnItems.Select(i => GetDto(i, user, fields));
+            var tuples = ibnItems.Select(i => new Tuple<TItemType, List<BaseItem>>(i, i.GetTaggedItems(libraryItems).ToList()));
+
+            var dtos = tuples.Select(i => GetDto(i.Item1, user, fields, i.Item2));
 
             result.Items = dtos.Where(i => i != null).ToArray();
 
             return result;
         }
 
-        private IEnumerable<TItemType> FilterByLibraryItems(GetItemsByName request, IEnumerable<TItemType> items, User user)
+        private IEnumerable<TItemType> FilterByLibraryItems(GetItemsByName request, IEnumerable<TItemType> items, User user, IEnumerable<BaseItem> libraryItems)
         {
             var filters = request.GetFilters().ToList();
 
             if (filters.Contains(ItemFilter.IsPlayed))
             {
-                var libraryItems = user.RootFolder.GetRecursiveChildren(user).ToList();
-
-                items = items.Where(i => GetLibraryItems(i, libraryItems).All(l => l.IsPlayed(user)));
+                items = items.Where(i => i.GetTaggedItems(libraryItems).All(l => l.IsPlayed(user)));
             }
 
             if (filters.Contains(ItemFilter.IsUnplayed))
             {
-                var libraryItems = user.RootFolder.GetRecursiveChildren(user).ToList();
-
-                items = items.Where(i => GetLibraryItems(i, libraryItems).All(l => l.IsUnplayed(user)));
+                items = items.Where(i => i.GetTaggedItems(libraryItems).All(l => l.IsUnplayed(user)));
             }
 
             if (request.IsPlayed.HasValue)
             {
                 var val = request.IsPlayed.Value;
 
-                var libraryItems = user.RootFolder.GetRecursiveChildren(user).ToList();
-
-                items = items.Where(i => GetLibraryItems(i, libraryItems).All(l => l.IsPlayed(user)) == val);
+                items = items.Where(i => i.GetTaggedItems(libraryItems).All(l => l.IsPlayed(user)) == val);
             }
 
             return items;
         }
 
-        protected abstract IEnumerable<BaseItem> GetLibraryItems(TItemType item, IEnumerable<BaseItem> libraryItems);
-
         /// <summary>
         /// Filters the items.
         /// </summary>
@@ -176,7 +176,7 @@ namespace MediaBrowser.Api.UserLibrary
             }
             if (!string.IsNullOrEmpty(request.NameStartsWith))
             {
-               items = items.Where(i => string.Compare(request.NameStartsWith, i.SortName.Substring(0, 1), StringComparison.CurrentCultureIgnoreCase) == 0);
+                items = items.Where(i => string.Compare(request.NameStartsWith, i.SortName.Substring(0, 1), StringComparison.CurrentCultureIgnoreCase) == 0);
             }
 
             if (!string.IsNullOrEmpty(request.NameLessThan))
@@ -292,11 +292,11 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="item">The item.</param>
         /// <param name="user">The user.</param>
         /// <param name="fields">The fields.</param>
+        /// <param name="libraryItems">The library items.</param>
         /// <returns>Task{DtoBaseItem}.</returns>
-        private BaseItemDto GetDto(TItemType item, User user, List<ItemFields> fields)
+        private BaseItemDto GetDto(TItemType item, User user, List<ItemFields> fields, List<BaseItem> libraryItems)
         {
-            var dto = user == null ? DtoService.GetBaseItemDto(item, fields) :
-                 DtoService.GetBaseItemDto(item, fields, user);
+            var dto = DtoService.GetItemByNameDto(item, fields, libraryItems, user);
 
             return dto;
         }
@@ -322,7 +322,7 @@ namespace MediaBrowser.Api.UserLibrary
 
         [ApiMember(Name = "NameLessThan", Description = "Optional filter by items whose name is sorted less than a given input string.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
         public string NameLessThan { get; set; }
-        
+
         public GetItemsByName()
         {
             Recursive = true;

+ 2 - 7
MediaBrowser.Api/UserLibrary/GameGenresService.cs

@@ -76,10 +76,10 @@ namespace MediaBrowser.Api.UserLibrary
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
 
-                return DtoService.GetBaseItemDto(item, fields.ToList(), user);
+                return DtoService.GetItemByNameDto(item, fields.ToList(), user);
             }
 
-            return DtoService.GetBaseItemDto(item, fields.ToList());
+            return DtoService.GetItemByNameDto(item, fields.ToList());
         }
 
         /// <summary>
@@ -109,10 +109,5 @@ namespace MediaBrowser.Api.UserLibrary
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Select(name => LibraryManager.GetGameGenre(name));
         }
-
-        protected override IEnumerable<BaseItem> GetLibraryItems(GameGenre item, IEnumerable<BaseItem> libraryItems)
-        {
-            return libraryItems.Where(i => (i is Game) && i.Genres.Contains(item.Name, StringComparer.OrdinalIgnoreCase));
-        }
     }
 }

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

@@ -81,10 +81,10 @@ namespace MediaBrowser.Api.UserLibrary
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
 
-                return DtoService.GetBaseItemDto(item, fields.ToList(), user);
+                return DtoService.GetItemByNameDto(item, fields.ToList(), user);
             }
 
-            return DtoService.GetBaseItemDto(item, fields.ToList());
+            return DtoService.GetItemByNameDto(item, fields.ToList());
         }
 
         /// <summary>
@@ -112,10 +112,5 @@ namespace MediaBrowser.Api.UserLibrary
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Select(name => LibraryManager.GetGenre(name));
         }
-
-        protected override IEnumerable<BaseItem> GetLibraryItems(Genre item, IEnumerable<BaseItem> libraryItems)
-        {
-            return libraryItems.Where(i => !(i is Game) && !(i is IHasMusicGenres) && i.Genres.Contains(item.Name, StringComparer.OrdinalIgnoreCase));
-        }
     }
 }

+ 2 - 7
MediaBrowser.Api/UserLibrary/MusicGenresService.cs

@@ -76,10 +76,10 @@ namespace MediaBrowser.Api.UserLibrary
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
 
-                return  DtoService.GetBaseItemDto(item, fields.ToList(), user);
+                return DtoService.GetItemByNameDto(item, fields.ToList(), user);
             }
 
-            return  DtoService.GetBaseItemDto(item, fields.ToList());
+            return DtoService.GetItemByNameDto(item, fields.ToList());
         }
 
         /// <summary>
@@ -109,10 +109,5 @@ namespace MediaBrowser.Api.UserLibrary
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Select(name => LibraryManager.GetMusicGenre(name));
         }
-
-        protected override IEnumerable<BaseItem> GetLibraryItems(MusicGenre item, IEnumerable<BaseItem> libraryItems)
-        {
-            return libraryItems.Where(i => (i is IHasMusicGenres) && i.Genres.Contains(item.Name, StringComparer.OrdinalIgnoreCase));
-        }
     }
 }

+ 2 - 7
MediaBrowser.Api/UserLibrary/PersonsService.cs

@@ -93,10 +93,10 @@ namespace MediaBrowser.Api.UserLibrary
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
 
-                return DtoService.GetBaseItemDto(item, fields.ToList(), user);
+                return DtoService.GetItemByNameDto(item, fields.ToList(), user);
             }
 
-            return DtoService.GetBaseItemDto(item, fields.ToList());
+            return DtoService.GetItemByNameDto(item, fields.ToList());
         }
 
         /// <summary>
@@ -163,10 +163,5 @@ namespace MediaBrowser.Api.UserLibrary
 
                 people.Where(p => personTypes.Contains(p.Type ?? string.Empty, StringComparer.OrdinalIgnoreCase) || personTypes.Contains(p.Role ?? string.Empty, StringComparer.OrdinalIgnoreCase));
         }
-
-        protected override IEnumerable<BaseItem> GetLibraryItems(Person item, IEnumerable<BaseItem> libraryItems)
-        {
-            return libraryItems.Where(i => i.People.Any(p => string.Equals(p.Name, item.Name, StringComparison.OrdinalIgnoreCase)));
-        }
     }
 }

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

@@ -81,10 +81,10 @@ namespace MediaBrowser.Api.UserLibrary
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
 
-                return DtoService.GetBaseItemDto(item, fields.ToList(), user);
+                return DtoService.GetItemByNameDto(item, fields.ToList(), user);
             }
 
-            return DtoService.GetBaseItemDto(item, fields.ToList());
+            return DtoService.GetItemByNameDto(item, fields.ToList());
         }
 
         /// <summary>
@@ -114,10 +114,5 @@ namespace MediaBrowser.Api.UserLibrary
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Select(name => LibraryManager.GetStudio(name));
         }
-
-        protected override IEnumerable<BaseItem> GetLibraryItems(Studio item, IEnumerable<BaseItem> libraryItems)
-        {
-            return libraryItems.Where(i => i.Studios.Contains(item.Name, StringComparer.OrdinalIgnoreCase));
-        }
     }
 }

+ 2 - 17
MediaBrowser.Api/UserLibrary/YearsService.cs

@@ -7,7 +7,6 @@ using MediaBrowser.Model.Querying;
 using ServiceStack;
 using System;
 using System.Collections.Generic;
-using System.Globalization;
 using System.Linq;
 
 namespace MediaBrowser.Api.UserLibrary
@@ -81,10 +80,10 @@ namespace MediaBrowser.Api.UserLibrary
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
 
-                return DtoService.GetBaseItemDto(item, fields.ToList(), user);
+                return DtoService.GetItemByNameDto(item, fields.ToList(), user);
             }
 
-            return DtoService.GetBaseItemDto(item, fields.ToList());
+            return DtoService.GetItemByNameDto(item, fields.ToList());
         }
 
         /// <summary>
@@ -115,19 +114,5 @@ namespace MediaBrowser.Api.UserLibrary
                 .Distinct()
                 .Select(year => LibraryManager.GetYear(year));
         }
-
-        protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
-        
-        protected override IEnumerable<BaseItem> GetLibraryItems(Year item, IEnumerable<BaseItem> libraryItems)
-        {
-            int year;
-
-            if (!int.TryParse(item.Name, NumberStyles.Integer, UsCulture, out year))
-            {
-                return libraryItems;
-            }
-
-            return libraryItems.Where(i => i.ProductionYear.HasValue && i.ProductionYear.Value == year);
-        }
     }
 }

+ 67 - 0
MediaBrowser.Controller/Channels/ChannelItemInfo.cs

@@ -0,0 +1,67 @@
+using MediaBrowser.Controller.Entities;
+using System.Collections.Generic;
+
+namespace MediaBrowser.Controller.Channels
+{
+    public class ChannelItemInfo
+    {
+        public string Name { get; set; }
+
+        public string Id { get; set; }
+
+        public ChannelItemType Type { get; set; }
+
+        public string OfficialRating { get; set; }
+
+        public string Overview { get; set; }
+
+        public List<string> Genres { get; set; }
+
+        public List<PersonInfo> People { get; set; }
+        
+        public float? CommunityRating { get; set; }
+
+        public long? RunTimeTicks { get; set; }
+
+        public bool IsInfinite { get; set; }
+        
+        public string ImageUrl { get; set; }
+
+        public ChannelMediaType MediaType { get; set; }
+
+        public ChannelMediaContentType ContentType { get; set; }
+        
+        public ChannelItemInfo()
+        {
+            Genres = new List<string>();
+            People = new List<PersonInfo>();
+        }
+    }
+
+    public enum ChannelItemType
+    {
+        Media = 0,
+
+        Category = 1
+    }
+
+    public enum ChannelMediaType
+    {
+        Audio = 0,
+
+        Video = 1
+    }
+
+    public enum ChannelMediaContentType
+    {
+        Clip = 0,
+
+        Podcast = 1,
+
+        Trailer = 2,
+
+        Movie = 3,
+
+        Episode = 4
+    }
+}

+ 57 - 0
MediaBrowser.Controller/Channels/IChannel.cs

@@ -0,0 +1,57 @@
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Controller.Channels
+{
+    public interface IChannel
+    {
+        /// <summary>
+        /// Gets the name.
+        /// </summary>
+        /// <value>The name.</value>
+        string Name { get; }
+
+        /// <summary>
+        /// Gets the home page URL.
+        /// </summary>
+        /// <value>The home page URL.</value>
+        string HomePageUrl { get; }
+
+        /// <summary>
+        /// Gets the capabilities.
+        /// </summary>
+        /// <returns>ChannelCapabilities.</returns>
+        ChannelCapabilities GetCapabilities();
+
+        /// <summary>
+        /// Searches the specified search term.
+        /// </summary>
+        /// <param name="searchTerm">The search term.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task{IEnumerable{ChannelItemInfo}}.</returns>
+        Task<IEnumerable<ChannelItemInfo>> Search(string searchTerm, CancellationToken cancellationToken);
+        
+        /// <summary>
+        /// Gets the channel items.
+        /// </summary>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task{IEnumerable{ChannelItem}}.</returns>
+        Task<IEnumerable<ChannelItemInfo>> GetChannelItems(CancellationToken cancellationToken);
+
+        /// <summary>
+        /// Gets the channel items.
+        /// </summary>
+        /// <param name="categoryId">The category identifier.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task{IEnumerable{ChannelItem}}.</returns>
+        Task<IEnumerable<ChannelItemInfo>> GetChannelItems(string categoryId, CancellationToken cancellationToken);
+    }
+
+    public class ChannelCapabilities
+    {
+        public bool CanSearch { get; set; }
+
+        public bool CanBeIndexed { get; set; }
+    }
+}

+ 12 - 0
MediaBrowser.Controller/Channels/IChannelManager.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Controller.Channels
+{
+    public interface IChannelManager
+    {
+    }
+}

+ 21 - 0
MediaBrowser.Controller/Dto/IDtoService.cs

@@ -73,5 +73,26 @@ namespace MediaBrowser.Controller.Dto
         /// <param name="owner">The owner.</param>
         /// <returns>Task{BaseItemDto}.</returns>
         BaseItemDto GetBaseItemDto(BaseItem item, List<ItemFields> fields, User user = null, BaseItem owner = null);
+
+        /// <summary>
+        /// Gets the item by name dto.
+        /// </summary>
+        /// <param name="item">The item.</param>
+        /// <param name="fields">The fields.</param>
+        /// <param name="user">The user.</param>
+        /// <returns>BaseItemDto.</returns>
+        BaseItemDto GetItemByNameDto<T>(T item, List<ItemFields> fields, User user = null)
+            where T : BaseItem, IItemByName;
+
+        /// <summary>
+        /// Gets the item by name dto.
+        /// </summary>
+        /// <param name="item">The item.</param>
+        /// <param name="fields">The fields.</param>
+        /// <param name="taggedItems">The tagged items.</param>
+        /// <param name="user">The user.</param>
+        /// <returns>BaseItemDto.</returns>
+        BaseItemDto GetItemByNameDto<T>(T item, List<ItemFields> fields, List<BaseItem> taggedItems, User user = null)
+            where T : BaseItem, IItemByName;
     }
 }

+ 18 - 0
MediaBrowser.Controller/Entities/Audio/Audio.cs

@@ -66,6 +66,24 @@ namespace MediaBrowser.Controller.Entities.Audio
         /// <value>The artist.</value>
         public List<string> Artists { get; set; }
 
+        [IgnoreDataMember]
+        public List<string> AllArtists
+        {
+            get
+            {
+                var list = new List<string>();
+
+                if (!string.IsNullOrEmpty(AlbumArtist))
+                {
+                    list.Add(AlbumArtist);
+                }
+                list.AddRange(Artists);
+
+                return list;
+
+            }
+        }
+
         /// <summary>
         /// Gets or sets the album.
         /// </summary>

+ 5 - 6
MediaBrowser.Controller/Entities/Audio/MusicArtist.cs

@@ -1,12 +1,10 @@
 using MediaBrowser.Common.Progress;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Runtime.Serialization;
 using System.Threading;
 using System.Threading.Tasks;
 
@@ -17,9 +15,6 @@ namespace MediaBrowser.Controller.Entities.Audio
     /// </summary>
     public class MusicArtist : Folder, IMetadataContainer, IItemByName, IHasMusicGenres, IHasDualAccess, IHasTags, IHasProductionLocations, IHasLookupInfo<ArtistInfo>
     {
-        [IgnoreDataMember]
-        public List<ItemByNameCounts> UserItemCountList { get; set; }
-
         public bool IsAccessedByName { get; set; }
 
         /// <summary>
@@ -65,7 +60,6 @@ namespace MediaBrowser.Controller.Entities.Audio
 
         public MusicArtist()
         {
-            UserItemCountList = new List<ItemByNameCounts>();
             Tags = new List<string>();
             ProductionLocations = new List<string>();
         }
@@ -230,5 +224,10 @@ namespace MediaBrowser.Controller.Entities.Audio
 
             return info;
         }
+
+        public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems)
+        {
+            return inputItems.OfType<IHasArtist>().Where(i => i.HasArtist(Name)).Cast<BaseItem>();
+        }
     }
 }

+ 7 - 11
MediaBrowser.Controller/Entities/Audio/MusicGenre.cs

@@ -1,7 +1,6 @@
-using System.Runtime.Serialization;
-using MediaBrowser.Model.Dto;
-using System;
+using System;
 using System.Collections.Generic;
+using System.Linq;
 
 namespace MediaBrowser.Controller.Entities.Audio
 {
@@ -10,11 +9,6 @@ namespace MediaBrowser.Controller.Entities.Audio
     /// </summary>
     public class MusicGenre : BaseItem, IItemByName
     {
-        public MusicGenre()
-        {
-            UserItemCountList = new List<ItemByNameCounts>();
-        }
-
         /// <summary>
         /// Gets the user data key.
         /// </summary>
@@ -24,9 +18,6 @@ namespace MediaBrowser.Controller.Entities.Audio
             return "MusicGenre-" + Name;
         }
 
-        [IgnoreDataMember]
-        public List<ItemByNameCounts> UserItemCountList { get; set; }
-
         /// <summary>
         /// Returns the folder containing the item.
         /// If the item is a folder, it returns the folder itself
@@ -51,5 +42,10 @@ namespace MediaBrowser.Controller.Entities.Audio
                 return false;
             }
         }
+
+        public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems)
+        {
+            return inputItems.Where(i => (i is IHasMusicGenres) && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase));
+        }
     }
 }

+ 7 - 10
MediaBrowser.Controller/Entities/GameGenre.cs

@@ -1,16 +1,11 @@
-using MediaBrowser.Model.Dto;
+using System;
 using System.Collections.Generic;
-using System.Runtime.Serialization;
+using System.Linq;
 
 namespace MediaBrowser.Controller.Entities
 {
     public class GameGenre : BaseItem, IItemByName
     {
-        public GameGenre()
-        {
-            UserItemCountList = new List<ItemByNameCounts>();
-        }
-
         /// <summary>
         /// Gets the user data key.
         /// </summary>
@@ -20,9 +15,6 @@ namespace MediaBrowser.Controller.Entities
             return "GameGenre-" + Name;
         }
 
-        [IgnoreDataMember]
-        public List<ItemByNameCounts> UserItemCountList { get; set; }
-
         /// <summary>
         /// Returns the folder containing the item.
         /// If the item is a folder, it returns the folder itself
@@ -47,5 +39,10 @@ namespace MediaBrowser.Controller.Entities
                 return false;
             }
         }
+
+        public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems)
+        {
+            return inputItems.Where(i => (i is Game) && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase));
+        }
     }
 }

+ 8 - 10
MediaBrowser.Controller/Entities/Genre.cs

@@ -1,6 +1,7 @@
-using MediaBrowser.Model.Dto;
+using MediaBrowser.Controller.Entities.Audio;
+using System;
 using System.Collections.Generic;
-using System.Runtime.Serialization;
+using System.Linq;
 
 namespace MediaBrowser.Controller.Entities
 {
@@ -9,11 +10,6 @@ namespace MediaBrowser.Controller.Entities
     /// </summary>
     public class Genre : BaseItem, IItemByName
     {
-        public Genre()
-        {
-            UserItemCountList = new List<ItemByNameCounts>();
-        }
-
         /// <summary>
         /// Gets the user data key.
         /// </summary>
@@ -23,9 +19,6 @@ namespace MediaBrowser.Controller.Entities
             return "Genre-" + Name;
         }
 
-        [IgnoreDataMember]
-        public List<ItemByNameCounts> UserItemCountList { get; set; }
-
         /// <summary>
         /// Returns the folder containing the item.
         /// If the item is a folder, it returns the folder itself
@@ -50,5 +43,10 @@ namespace MediaBrowser.Controller.Entities
                 return false;
             }
         }
+
+        public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems)
+        {
+            return inputItems.Where(i => !(i is Game) && !(i is IHasMusicGenres) && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase));
+        }
     }
 }

+ 7 - 31
MediaBrowser.Controller/Entities/IItemByName.cs

@@ -1,7 +1,4 @@
-using MediaBrowser.Model.Dto;
-using System;
-using System.Collections.Generic;
-using System.Linq;
+using System.Collections.Generic;
 
 namespace MediaBrowser.Controller.Entities
 {
@@ -10,37 +7,16 @@ namespace MediaBrowser.Controller.Entities
     /// </summary>
     public interface IItemByName
     {
-        List<ItemByNameCounts> UserItemCountList { get; set; }
+        /// <summary>
+        /// Gets the tagged items.
+        /// </summary>
+        /// <param name="inputItems">The input items.</param>
+        /// <returns>IEnumerable{BaseItem}.</returns>
+        IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems);
     }
 
     public interface IHasDualAccess : IItemByName
     {
         bool IsAccessedByName { get; }
     }
-
-    public static class ItemByNameExtensions
-    {
-        public static ItemByNameCounts GetItemByNameCounts(this IItemByName item, Guid userId)
-        {
-            if (userId == Guid.Empty)
-            {
-                throw new ArgumentNullException("userId");
-            }
-
-            return item.UserItemCountList.FirstOrDefault(i => i.UserId == userId);
-        }
-
-        public static void SetItemByNameCounts(this IItemByName item, Guid userId, ItemByNameCounts counts)
-        {
-            var current = item.UserItemCountList.FirstOrDefault(i => i.UserId == userId);
-
-            if (current != null)
-            {
-                item.UserItemCountList.Remove(current);
-            }
-
-            counts.UserId = userId;
-            item.UserItemCountList.Add(counts);
-        }
-    }
 }

+ 7 - 10
MediaBrowser.Controller/Entities/Person.cs

@@ -1,7 +1,7 @@
 using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Dto;
+using System;
 using System.Collections.Generic;
-using System.Runtime.Serialization;
+using System.Linq;
 
 namespace MediaBrowser.Controller.Entities
 {
@@ -10,19 +10,11 @@ namespace MediaBrowser.Controller.Entities
     /// </summary>
     public class Person : BaseItem, IItemByName, IHasLookupInfo<PersonLookupInfo>
     {
-        public Person()
-        {
-            UserItemCountList = new List<ItemByNameCounts>();
-        }
-
         /// <summary>
         /// Gets or sets the place of birth.
         /// </summary>
         /// <value>The place of birth.</value>
         public string PlaceOfBirth { get; set; }
-
-        [IgnoreDataMember]
-        public List<ItemByNameCounts> UserItemCountList { get; set; }
         
         /// <summary>
         /// Gets the user data key.
@@ -62,6 +54,11 @@ namespace MediaBrowser.Controller.Entities
                 return false;
             }
         }
+
+        public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems)
+        {
+            return inputItems.Where(i => i.People.Any(p => string.Equals(p.Name, Name, StringComparison.OrdinalIgnoreCase)));
+        }
     }
 
     /// <summary>

+ 7 - 11
MediaBrowser.Controller/Entities/Studio.cs

@@ -1,7 +1,6 @@
-using System.Runtime.Serialization;
-using MediaBrowser.Model.Dto;
-using System;
+using System;
 using System.Collections.Generic;
+using System.Linq;
 
 namespace MediaBrowser.Controller.Entities
 {
@@ -10,11 +9,6 @@ namespace MediaBrowser.Controller.Entities
     /// </summary>
     public class Studio : BaseItem, IItemByName
     {
-        public Studio()
-        {
-            UserItemCountList = new List<ItemByNameCounts>();
-        }
-
         /// <summary>
         /// Gets the user data key.
         /// </summary>
@@ -24,9 +18,6 @@ namespace MediaBrowser.Controller.Entities
             return "Studio-" + Name;
         }
 
-        [IgnoreDataMember]
-        public List<ItemByNameCounts> UserItemCountList { get; set; }
-
         /// <summary>
         /// Returns the folder containing the item.
         /// If the item is a folder, it returns the folder itself
@@ -51,5 +42,10 @@ namespace MediaBrowser.Controller.Entities
                 return false;
             }
         }
+
+        public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems)
+        {
+            return inputItems.Where(i => i.Studios.Contains(Name, StringComparer.OrdinalIgnoreCase));
+        }
     }
 }

+ 17 - 12
MediaBrowser.Controller/Entities/Year.cs

@@ -1,7 +1,6 @@
-using System.Runtime.Serialization;
-using MediaBrowser.Model.Dto;
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
 
 namespace MediaBrowser.Controller.Entities
 {
@@ -10,14 +9,6 @@ namespace MediaBrowser.Controller.Entities
     /// </summary>
     public class Year : BaseItem, IItemByName
     {
-        public Year()
-        {
-            UserItemCountList = new List<ItemByNameCounts>();
-        }
-
-        [IgnoreDataMember]
-        public List<ItemByNameCounts> UserItemCountList { get; set; }
-
         /// <summary>
         /// Gets the user data key.
         /// </summary>
@@ -51,5 +42,19 @@ namespace MediaBrowser.Controller.Entities
                 return false;
             }
         }
+
+        public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems)
+        {
+            int year;
+
+            var usCulture = new CultureInfo("en-US"); 
+            
+            if (!int.TryParse(Name, NumberStyles.Integer, usCulture, out year))
+            {
+                return inputItems;
+            }
+
+            return inputItems.Where(i => i.ProductionYear.HasValue && i.ProductionYear.Value == year);
+        }
     }
 }

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

@@ -304,19 +304,6 @@ namespace MediaBrowser.Controller.Library
         /// <returns>System.String.</returns>
         string FindCollectionType(BaseItem item);
 
-        /// <summary>
-        /// Gets all artists.
-        /// </summary>
-        /// <returns>IEnumerable{System.String}.</returns>
-        IEnumerable<string> GetAllArtists();
-
-        /// <summary>
-        /// Gets all artists.
-        /// </summary>
-        /// <param name="items">The items.</param>
-        /// <returns>IEnumerable{System.String}.</returns>
-        IEnumerable<string> GetAllArtists(IEnumerable<BaseItem> items);
-
         /// <summary>
         /// Normalizes the root path list.
         /// </summary>

+ 0 - 7
MediaBrowser.Controller/LiveTv/ILiveTvManager.cs

@@ -138,13 +138,6 @@ namespace MediaBrowser.Controller.LiveTv
         /// <param name="id">The identifier.</param>
         /// <returns>Channel.</returns>
         LiveTvChannel GetInternalChannel(string id);
-
-        /// <summary>
-        /// Gets the internal program.
-        /// </summary>
-        /// <param name="id">The identifier.</param>
-        /// <returns>LiveTvProgram.</returns>
-        LiveTvProgram GetInternalProgram(string id);
         
         /// <summary>
         /// Gets the recording.

+ 5 - 10
MediaBrowser.Controller/LiveTv/LiveTvChannel.cs

@@ -1,20 +1,13 @@
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.LiveTv;
 using System.Collections.Generic;
-using System.Runtime.Serialization;
 using System.Linq;
 
 namespace MediaBrowser.Controller.LiveTv
 {
     public class LiveTvChannel : BaseItem, IItemByName
     {
-        public LiveTvChannel()
-        {
-            UserItemCountList = new List<ItemByNameCounts>();
-        }
-
         /// <summary>
         /// Gets the user data key.
         /// </summary>
@@ -24,9 +17,6 @@ namespace MediaBrowser.Controller.LiveTv
             return GetClientTypeName() + "-" + Name;
         }
 
-        [IgnoreDataMember]
-        public List<ItemByNameCounts> UserItemCountList { get; set; }
-
         /// <summary>
         /// Returns the folder containing the item.
         /// If the item is a folder, it returns the folder itself
@@ -119,5 +109,10 @@ namespace MediaBrowser.Controller.LiveTv
         {
             return "Channel";
         }
+
+        public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems)
+        {
+            return new List<BaseItem>();
+        }
     }
 }

+ 3 - 0
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -68,6 +68,9 @@
     <Compile Include="..\SharedVersion.cs">
       <Link>Properties\SharedVersion.cs</Link>
     </Compile>
+    <Compile Include="Channels\ChannelItemInfo.cs" />
+    <Compile Include="Channels\IChannel.cs" />
+    <Compile Include="Channels\IChannelManager.cs" />
     <Compile Include="Collections\CollectionCreationOptions.cs" />
     <Compile Include="Collections\ICollectionManager.cs" />
     <Compile Include="Drawing\IImageProcessor.cs" />

+ 0 - 7
MediaBrowser.Model/Querying/ItemSortBy.cs

@@ -75,13 +75,6 @@ namespace MediaBrowser.Model.Querying
         public const string IsFolder = "IsFolder";
         public const string IsUnplayed = "IsUnplayed";
         public const string IsPlayed = "IsPlayed";
-        public const string TrailerCount = "TrailerCount";
-        public const string MovieCount = "MovieCount";
-        public const string SeriesCount = "SeriesCount";
-        public const string EpisodeCount = "EpisodeCount";
-        public const string SongCount = "SongCount";
-        public const string AlbumCount = "AlbumCount";
-        public const string MusicVideoCount = "MusicVideoCount";
         public const string SeriesSortName = "SeriesSortName";
         public const string VideoBitRate = "VideoBitRate";
         public const string AirTime = "AirTime";

+ 36 - 26
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -121,41 +121,51 @@ namespace MediaBrowser.Server.Implementations.Dto
                 }
             }
 
-            var itemByName = item as IItemByName;
-            if (itemByName != null)
-            {
-                AttachItemByNameCounts(dto, itemByName, user);
-            }
-
             return dto;
         }
 
-        /// <summary>
-        /// Attaches the item by name counts.
-        /// </summary>
-        /// <param name="dto">The dto.</param>
-        /// <param name="item">The item.</param>
-        /// <param name="user">The user.</param>
-        private void AttachItemByNameCounts(BaseItemDto dto, IItemByName item, User user)
+        public BaseItemDto GetItemByNameDto<T>(T item, List<ItemFields> fields, User user = null)
+            where T : BaseItem, IItemByName
         {
-            if (user == null)
+            var libraryItems = user != null ? user.RootFolder.GetRecursiveChildren(user) : 
+                _libraryManager.RootFolder.RecursiveChildren;
+
+            return GetItemByNameDto(item, fields, item.GetTaggedItems(libraryItems).ToList(), user);
+        }
+
+        public BaseItemDto GetItemByNameDto<T>(T item, List<ItemFields> fields, List<BaseItem> taggedItems, User user = null)
+            where T : BaseItem, IItemByName
+        {
+            var dto = GetBaseItemDto(item, fields, user);
+
+            if (item is MusicArtist || item is MusicGenre)
             {
-                return;
+                dto.AlbumCount = taggedItems.Count(i => i is MusicAlbum);
+                dto.MusicVideoCount = taggedItems.Count(i => i is MusicVideo);
+                dto.SongCount = taggedItems.Count(i => i is Audio);
+            }
+            else if (item is GameGenre)
+            {
+                dto.GameCount = taggedItems.Count(i => i is Game);
             }
+            else
+            {
+                // This populates them all and covers Genre, Person, Studio, Year
 
-            var counts = item.GetItemByNameCounts(user.Id) ?? new ItemByNameCounts();
+                dto.AdultVideoCount = taggedItems.Count(i => i is AdultVideo);
+                dto.AlbumCount = taggedItems.Count(i => i is MusicAlbum);
+                dto.EpisodeCount = taggedItems.Count(i => i is Episode);
+                dto.GameCount = taggedItems.Count(i => i is Game);
+                dto.MovieCount = taggedItems.Count(i => i is Movie);
+                dto.MusicVideoCount = taggedItems.Count(i => i is MusicVideo);
+                dto.SeriesCount = taggedItems.Count(i => i is Series);
+                dto.SongCount = taggedItems.Count(i => i is Audio);
+                dto.TrailerCount = taggedItems.Count(i => i is Trailer);
+            }
 
-            dto.ChildCount = counts.TotalCount;
+            dto.ChildCount = taggedItems.Count;
 
-            dto.AdultVideoCount = counts.AdultVideoCount;
-            dto.AlbumCount = counts.AlbumCount;
-            dto.EpisodeCount = counts.EpisodeCount;
-            dto.GameCount = counts.GameCount;
-            dto.MovieCount = counts.MovieCount;
-            dto.MusicVideoCount = counts.MusicVideoCount;
-            dto.SeriesCount = counts.SeriesCount;
-            dto.SongCount = counts.SongCount;
-            dto.TrailerCount = counts.TrailerCount;
+            return dto;
         }
 
         /// <summary>

+ 6 - 3
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -484,6 +484,9 @@ namespace MediaBrowser.Server.Implementations.Library
                 await ItemRepository.DeleteItem(child.Id, CancellationToken.None).ConfigureAwait(false);
             }
 
+            BaseItem removed;
+            _libraryItemsCache.TryRemove(item.Id, out removed);
+
             ReportItemRemoved(item);
         }
 
@@ -922,10 +925,10 @@ namespace MediaBrowser.Server.Implementations.Library
         /// <returns>Task.</returns>
         public Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress)
         {
-            // Ensure the location is unavailable.
+            // Ensure the location is available.
             Directory.CreateDirectory(ConfigurationManager.ApplicationPaths.PeoplePath);
 
-            return new PeopleValidator(this, _logger).ValidatePeople(cancellationToken, progress);
+            return new PeopleValidator(this, _logger).ValidatePeople(cancellationToken, new MetadataRefreshOptions(), progress);
         }
 
         /// <summary>
@@ -953,7 +956,7 @@ namespace MediaBrowser.Server.Implementations.Library
             // Ensure the location is unavailable.
             Directory.CreateDirectory(ConfigurationManager.ApplicationPaths.MusicGenrePath);
             
-            return new MusicGenresValidator(this, _userManager, _logger).Run(progress, cancellationToken);
+            return new MusicGenresValidator(this, _logger).Run(progress, cancellationToken);
         }
 
         /// <summary>

+ 3 - 1
MediaBrowser.Server.Implementations/Library/SearchEngine.cs

@@ -102,7 +102,9 @@ namespace MediaBrowser.Server.Implementations.Library
             if (query.IncludeArtists)
             {
                 // Find artists
-                var artists = _libraryManager.GetAllArtists(items)
+                var artists = items.OfType<Audio>()
+                    .SelectMany(i => i.AllArtists)
+                    .Distinct(StringComparer.OrdinalIgnoreCase)
                     .ToList();
 
                 foreach (var item in artists)

+ 2 - 43
MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs

@@ -1,8 +1,6 @@
 using MediaBrowser.Common.Progress;
-using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
 using System;
@@ -69,10 +67,6 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
 
             var numComplete = 0;
 
-            var userLibraries = _userManager.Users
-                .Select(i => new Tuple<Guid, List<IHasArtist>>(i.Id, i.RootFolder.GetRecursiveChildren(i).OfType<IHasArtist>().ToList()))
-                .ToList();
-
             var numArtists = allArtists.Count;
 
             foreach (var artist in allArtists)
@@ -91,11 +85,6 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
                         .ToList();
                 }
 
-                foreach (var lib in userLibraries)
-                {
-                    SetItemCounts(artist, lib.Item1, lib.Item2);
-                }
-
                 numComplete++;
                 double percent = numComplete;
                 percent /= numArtists;
@@ -107,37 +96,6 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
             progress.Report(100);
         }
 
-        /// <summary>
-        /// Sets the item counts.
-        /// </summary>
-        /// <param name="artist">The artist.</param>
-        /// <param name="userId">The user id.</param>
-        /// <param name="allItems">All items.</param>
-        private void SetItemCounts(MusicArtist artist, Guid? userId, IEnumerable<IHasArtist> allItems)
-        {
-            var name = artist.Name;
-
-            var items = allItems
-                .Where(i => i.HasArtist(name))
-                .ToList();
-
-            var counts = new ItemByNameCounts
-            {
-                TotalCount = items.Count,
-
-                SongCount = items.OfType<Audio>().Count(),
-
-                AlbumCount = items.OfType<MusicAlbum>().Count(),
-
-                MusicVideoCount = items.OfType<MusicVideo>().Count()
-            };
-
-            if (userId.HasValue)
-            {
-                artist.SetItemByNameCounts(userId.Value, counts);
-            }
-        }
-
         /// <summary>
         /// Gets all artists.
         /// </summary>
@@ -147,7 +105,8 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// <returns>Task{Artist[]}.</returns>
         private async Task<List<MusicArtist>> GetAllArtists(IEnumerable<Audio> allSongs, CancellationToken cancellationToken, IProgress<double> progress)
         {
-            var allArtists = _libraryManager.GetAllArtists(allSongs)
+            var allArtists = allSongs.SelectMany(i => i.AllArtists)
+                .Distinct(StringComparer.OrdinalIgnoreCase)
                 .ToList();
 
             var returnArtists = new List<MusicArtist>(allArtists.Count);

+ 10 - 52
MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs

@@ -2,7 +2,6 @@
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Logging;
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -41,38 +40,24 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// <returns>Task.</returns>
         public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
-            var userLibraries = _userManager.Users
-                .Select(i => new Tuple<Guid, List<Game>>(i.Id, i.RootFolder.GetRecursiveChildren(i).OfType<Game>().ToList()))
+            var items = _libraryManager.RootFolder.RecursiveChildren.Where(i => (i is Game))
+                .SelectMany(i => i.Genres)
+                .Distinct(StringComparer.OrdinalIgnoreCase)
                 .ToList();
 
-            var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>>(StringComparer.OrdinalIgnoreCase);
-
             progress.Report(2);
-
             var numComplete = 0;
+            var count = items.Count;
 
-            foreach (var lib in userLibraries)
+            foreach (var name in items)
             {
-                SetItemCounts(lib.Item1, lib.Item2, masterDictionary);
-
-                numComplete++;
-                double percent = numComplete;
-                percent /= userLibraries.Count;
-                percent *= 8;
-
-                progress.Report(percent);
-            }
+                cancellationToken.ThrowIfCancellationRequested();
 
-            progress.Report(10);
-
-            var count = masterDictionary.Count;
-            numComplete = 0;
-
-            foreach (var name in masterDictionary.Keys)
-            {
                 try
                 {
-                    await UpdateItemByNameCounts(name, cancellationToken, masterDictionary[name]).ConfigureAwait(false);
+                    var itemByName = _libraryManager.GetGameGenre(name);
+
+                    await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
                 }
                 catch (OperationCanceledException)
                 {
@@ -81,7 +66,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
                 }
                 catch (Exception ex)
                 {
-                    _logger.ErrorException("Error updating counts for {0}", ex, name);
+                    _logger.ErrorException("Error refreshing {0}", ex, name);
                 }
 
                 numComplete++;
@@ -94,32 +79,5 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
 
             progress.Report(100);
         }
-
-        private Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<CountType, int>> counts)
-        {
-            var itemByName = _libraryManager.GetGameGenre(name);
-
-            foreach (var libraryId in counts.Keys)
-            {
-                var itemCounts = CountHelpers.GetCounts(counts[libraryId]);
-
-                itemByName.SetItemByNameCounts(libraryId, itemCounts);
-            }
-
-            return itemByName.RefreshMetadata(cancellationToken);
-        }
-
-        private void SetItemCounts(Guid userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>> masterDictionary)
-        {
-            foreach (var media in allItems)
-            {
-                var names = media
-                    .Genres
-                    .Distinct(StringComparer.OrdinalIgnoreCase)
-                    .ToList();
-
-                CountHelpers.SetItemCounts(userId, media, names, masterDictionary);
-            }
-        }
     }
 }

+ 10 - 52
MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs

@@ -3,7 +3,6 @@ using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Logging;
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -42,38 +41,24 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// <returns>Task.</returns>
         public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
-            var userLibraries = _userManager.Users
-                .Select(i => new Tuple<Guid, IList<BaseItem>>(i.Id, i.RootFolder.GetRecursiveChildren(i, m => !(m is IHasMusicGenres) && !(m is Game))))
+            var items = _libraryManager.RootFolder.RecursiveChildren.Where(i => !(i is IHasMusicGenres) && !(i is Game))
+                .SelectMany(i => i.Genres)
+                .Distinct(StringComparer.OrdinalIgnoreCase)
                 .ToList();
 
-            var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>>(StringComparer.OrdinalIgnoreCase);
-
             progress.Report(2);
-
             var numComplete = 0;
+            var count = items.Count;
 
-            foreach (var lib in userLibraries)
+            foreach (var name in items)
             {
-                SetItemCounts(lib.Item1, lib.Item2, masterDictionary);
-
-                numComplete++;
-                double percent = numComplete;
-                percent /= userLibraries.Count;
-                percent *= 8;
-
-                progress.Report(percent);
-            }
+                cancellationToken.ThrowIfCancellationRequested();
 
-            progress.Report(10);
-
-            var count = masterDictionary.Count;
-            numComplete = 0;
-
-            foreach (var name in masterDictionary.Keys)
-            {
                 try
                 {
-                    await UpdateItemByNameCounts(name, cancellationToken, masterDictionary[name]).ConfigureAwait(false);
+                    var itemByName = _libraryManager.GetGenre(name);
+
+                    await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
                 }
                 catch (OperationCanceledException)
                 {
@@ -82,7 +67,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
                 }
                 catch (Exception ex)
                 {
-                    _logger.ErrorException("Error updating counts for {0}", ex, name);
+                    _logger.ErrorException("Error refreshing {0}", ex, name);
                 }
 
                 numComplete++;
@@ -95,32 +80,5 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
 
             progress.Report(100);
         }
-
-        private Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<CountType, int>> counts)
-        {
-            var itemByName = _libraryManager.GetGenre(name);
-
-            foreach (var libraryId in counts.Keys)
-            {
-                var itemCounts = CountHelpers.GetCounts(counts[libraryId]);
-
-                itemByName.SetItemByNameCounts(libraryId, itemCounts);
-            }
-
-            return itemByName.RefreshMetadata(cancellationToken);
-        }
-
-        private void SetItemCounts(Guid userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>> masterDictionary)
-        {
-            foreach (var media in allItems)
-            {
-                var names = media
-                    .Genres
-                    .Distinct(StringComparer.OrdinalIgnoreCase)
-                    .ToList();
-
-                CountHelpers.SetItemCounts(userId, media, names, masterDictionary);
-            }
-        }
     }
 }

+ 12 - 61
MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs

@@ -1,9 +1,7 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Logging;
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -17,20 +15,14 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// </summary>
         private readonly ILibraryManager _libraryManager;
 
-        /// <summary>
-        /// The _user manager
-        /// </summary>
-        private readonly IUserManager _userManager;
-
         /// <summary>
         /// The _logger
         /// </summary>
         private readonly ILogger _logger;
 
-        public MusicGenresValidator(ILibraryManager libraryManager, IUserManager userManager, ILogger logger)
+        public MusicGenresValidator(ILibraryManager libraryManager, ILogger logger)
         {
             _libraryManager = libraryManager;
-            _userManager = userManager;
             _logger = logger;
         }
 
@@ -42,38 +34,24 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// <returns>Task.</returns>
         public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
-            var userLibraries = _userManager.Users
-                .Select(i => new Tuple<Guid, IList<BaseItem>>(i.Id, i.RootFolder.GetRecursiveChildren(i, m => m is IHasMusicGenres)))
+            var items = _libraryManager.RootFolder.RecursiveChildren.Where(i => (i is IHasMusicGenres))
+                .SelectMany(i => i.Genres)
+                .Distinct(StringComparer.OrdinalIgnoreCase)
                 .ToList();
 
-            var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>>(StringComparer.OrdinalIgnoreCase);
-
             progress.Report(2);
-
             var numComplete = 0;
+            var count = items.Count;
 
-            foreach (var lib in userLibraries)
+            foreach (var name in items)
             {
-                SetItemCounts(lib.Item1, lib.Item2, masterDictionary);
-
-                numComplete++;
-                double percent = numComplete;
-                percent /= userLibraries.Count;
-                percent *= 8;
-
-                progress.Report(percent);
-            }
-
-            progress.Report(10);
+                cancellationToken.ThrowIfCancellationRequested();
 
-            var count = masterDictionary.Count;
-            numComplete = 0;
-
-            foreach (var name in masterDictionary.Keys)
-            {
                 try
                 {
-                    await UpdateItemByNameCounts(name, cancellationToken, masterDictionary[name]).ConfigureAwait(false);
+                    var itemByName = _libraryManager.GetMusicGenre(name);
+
+                    await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
                 }
                 catch (OperationCanceledException)
                 {
@@ -82,7 +60,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
                 }
                 catch (Exception ex)
                 {
-                    _logger.ErrorException("Error updating counts for {0}", ex, name);
+                    _logger.ErrorException("Error refreshing {0}", ex, name);
                 }
 
                 numComplete++;
@@ -95,32 +73,5 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
 
             progress.Report(100);
         }
-
-        private Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<CountType, int>> counts)
-        {
-            var itemByName = _libraryManager.GetMusicGenre(name);
-
-            foreach (var libraryId in counts.Keys)
-            {
-                var itemCounts = CountHelpers.GetCounts(counts[libraryId]);
-
-                itemByName.SetItemByNameCounts(libraryId, itemCounts);
-            }
-
-            return itemByName.RefreshMetadata(cancellationToken);
-        }
-
-        private void SetItemCounts(Guid userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>> masterDictionary)
-        {
-            foreach (var media in allItems)
-            {
-                var names = media
-                    .Genres
-                    .Distinct(StringComparer.OrdinalIgnoreCase)
-                    .ToList();
-
-                CountHelpers.SetItemCounts(userId, media, names, masterDictionary);
-            }
-        }
     }
 }

+ 6 - 97
MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs

@@ -1,10 +1,7 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Logging;
 using System;
-using System.Collections.Generic;
-using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 
@@ -17,20 +14,14 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// </summary>
         private readonly ILibraryManager _libraryManager;
 
-        /// <summary>
-        /// The _user manager
-        /// </summary>
-        private readonly IUserManager _userManager;
-
         /// <summary>
         /// The _logger
         /// </summary>
         private readonly ILogger _logger;
 
-        public PeoplePostScanTask(ILibraryManager libraryManager, IUserManager userManager, ILogger logger)
+        public PeoplePostScanTask(ILibraryManager libraryManager, ILogger logger)
         {
             _libraryManager = libraryManager;
-            _userManager = userManager;
             _logger = logger;
         }
 
@@ -42,94 +33,12 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// <returns>Task.</returns>
         public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
-            return RunInternal(progress, cancellationToken);
-        }
-
-        private async Task RunInternal(IProgress<double> progress, CancellationToken cancellationToken)
-        {
-            var userLibraries = _userManager.Users
-                .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);
-
-            progress.Report(2);
-
-            var numComplete = 0;
-
-            foreach (var lib in userLibraries)
+            return new PeopleValidator(_libraryManager, _logger).ValidatePeople(cancellationToken, new MetadataRefreshOptions
             {
-                cancellationToken.ThrowIfCancellationRequested();
-
-                SetItemCounts(lib.Item1, lib.Item2, masterDictionary);
-
-                numComplete++;
-                double percent = numComplete;
-                percent /= userLibraries.Count;
-                percent *= 8;
+                ImageRefreshMode = ImageRefreshMode.ValidationOnly,
+                MetadataRefreshMode = MetadataRefreshMode.None
 
-                progress.Report(percent);
-            }
-
-            progress.Report(10);
-
-            var count = masterDictionary.Count;
-            numComplete = 0;
-
-            foreach (var name in masterDictionary.Keys)
-            {
-                cancellationToken.ThrowIfCancellationRequested();
-
-                try
-                {
-                    var counts = masterDictionary[name];
-
-                    var itemByName = _libraryManager.GetPerson(name);
-
-                    // The only purpose here is to be able to react to image changes without running the people task. 
-                    // All other metadata can wait for that.
-                    await itemByName.RefreshMetadata(new MetadataRefreshOptions
-                    {
-                        ImageRefreshMode = ImageRefreshMode.ValidationOnly,
-                        MetadataRefreshMode = MetadataRefreshMode.None
-
-                    }, cancellationToken).ConfigureAwait(false);
-
-                    foreach (var libraryId in counts.Keys)
-                    {
-                        var itemCounts = CountHelpers.GetCounts(counts[libraryId]);
-
-                        itemByName.SetItemByNameCounts(libraryId, itemCounts);
-                    }
-                }
-                catch (Exception ex)
-                {
-                    _logger.ErrorException("Error updating counts for {0}", ex, name);
-                }
-
-                numComplete++;
-                double percent = numComplete;
-                percent /= count;
-                percent *= 90;
-
-                progress.Report(percent + 10);
-            }
-
-            progress.Report(100);
+            }, progress);
         }
-
-        private void SetItemCounts(Guid userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>> masterDictionary)
-        {
-            foreach (var media in allItems)
-            {
-                var names = media
-                    .People.Select(i => i.Name)
-                    .Distinct(StringComparer.OrdinalIgnoreCase)
-                    .ToList();
-
-                CountHelpers.SetItemCounts(userId, media, names, masterDictionary);
-            }
-        }
-
     }
 }

+ 4 - 2
MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs

@@ -1,5 +1,6 @@
 using MediaBrowser.Common.Progress;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Logging;
 using MoreLinq;
 using System;
@@ -38,9 +39,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// Validates the people.
         /// </summary>
         /// <param name="cancellationToken">The cancellation token.</param>
+        /// <param name="options">The options.</param>
         /// <param name="progress">The progress.</param>
         /// <returns>Task.</returns>
-        public async Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress)
+        public async Task ValidatePeople(CancellationToken cancellationToken, MetadataRefreshOptions options, IProgress<double> progress)
         {
             var innerProgress = new ActionableProgress<double>();
 
@@ -61,7 +63,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
                 {
                     var item = _libraryManager.GetPerson(person.Name);
 
-                    await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
+                    await item.RefreshMetadata(options, cancellationToken).ConfigureAwait(false);
                 }
                 catch (Exception ex)
                 {

+ 11 - 54
MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs

@@ -1,8 +1,6 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Logging;
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -41,38 +39,24 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// <returns>Task.</returns>
         public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
-            var userLibraries = _userManager.Users
-                .Select(i => new Tuple<Guid, IList<BaseItem>>(i.Id, i.RootFolder.GetRecursiveChildren(i, null)))
+            var items = _libraryManager.RootFolder.RecursiveChildren
+                .SelectMany(i => i.Studios)
+                .Distinct(StringComparer.OrdinalIgnoreCase)
                 .ToList();
 
-            var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>>(StringComparer.OrdinalIgnoreCase);
-
             progress.Report(2);
-
             var numComplete = 0;
+            var count = items.Count;
 
-            foreach (var lib in userLibraries)
+            foreach (var name in items)
             {
-                SetItemCounts(lib.Item1, lib.Item2, masterDictionary);
-
-                numComplete++;
-                double percent = numComplete;
-                percent /= userLibraries.Count;
-                percent *= 8;
-
-                progress.Report(percent);
-            }
+                cancellationToken.ThrowIfCancellationRequested();
 
-            progress.Report(10);
-
-            var count = masterDictionary.Count;
-            numComplete = 0;
-
-            foreach (var name in masterDictionary.Keys)
-            {
                 try
                 {
-                    await UpdateItemByNameCounts(name, cancellationToken, masterDictionary[name]).ConfigureAwait(false);
+                    var itemByName = _libraryManager.GetStudio(name);
+
+                    await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
                 }
                 catch (OperationCanceledException)
                 {
@@ -81,7 +65,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
                 }
                 catch (Exception ex)
                 {
-                    _logger.ErrorException("Error updating counts for {0}", ex, name);
+                    _logger.ErrorException("Error refreshing {0}", ex, name);
                 }
 
                 numComplete++;
@@ -94,32 +78,5 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
 
             progress.Report(100);
         }
-
-        private Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<CountType, int>> counts)
-        {
-            var itemByName = _libraryManager.GetStudio(name);
-
-            foreach (var libraryId in counts.Keys)
-            {
-                var itemCounts = CountHelpers.GetCounts(counts[libraryId]);
-
-                itemByName.SetItemByNameCounts(libraryId, itemCounts);
-            }
-
-            return itemByName.RefreshMetadata(cancellationToken);
-        }
-
-        private void SetItemCounts(Guid userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>> masterDictionary)
-        {
-            foreach (var media in allItems)
-            {
-                var names = media
-                    .Studios
-                    .Distinct(StringComparer.OrdinalIgnoreCase)
-                    .ToList();
-
-                CountHelpers.SetItemCounts(userId, media, names, masterDictionary);
-            }
-        }
     }
 }

+ 81 - 37
MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -47,6 +47,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
         private List<Guid> _channelIdList = new List<Guid>();
         private Dictionary<Guid, LiveTvProgram> _programs = new Dictionary<Guid, LiveTvProgram>();
+        private readonly ConcurrentDictionary<Guid, bool> _refreshedPrograms = new ConcurrentDictionary<Guid, bool>();
 
         private readonly SemaphoreSlim _refreshSemaphore = new SemaphoreSlim(1, 1);
 
@@ -106,7 +107,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             _taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
         }
 
-        public Task<QueryResult<ChannelInfoDto>> GetChannels(ChannelQuery query, CancellationToken cancellationToken)
+        public async Task<QueryResult<ChannelInfoDto>> GetChannels(ChannelQuery query, CancellationToken cancellationToken)
         {
             var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId));
 
@@ -161,17 +162,22 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 allEnumerable = allEnumerable.Take(query.Limit.Value);
             }
 
-            var returnChannels = allEnumerable
-                .Select(i => _tvDtoService.GetChannelInfoDto(i, GetCurrentProgram(i.ExternalId), user))
-                .ToArray();
+            var returnList = new List<ChannelInfoDto>();
+
+            foreach (var channel in allEnumerable)
+            {
+                var currentProgram = await GetCurrentProgram(channel.ExternalId, cancellationToken).ConfigureAwait(false);
+
+                returnList.Add(_tvDtoService.GetChannelInfoDto(channel, currentProgram, user));
+            }
 
             var result = new QueryResult<ChannelInfoDto>
             {
-                Items = returnChannels,
-                TotalRecordCount = allChannels.Count
+                Items = returnList.ToArray(),
+                TotalRecordCount = returnList.Count
             };
 
-            return Task.FromResult(result);
+            return result;
         }
 
         public LiveTvChannel GetInternalChannel(string id)
@@ -184,16 +190,41 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             return _libraryManager.GetItemById(id) as LiveTvChannel;
         }
 
-        public LiveTvProgram GetInternalProgram(string id)
+        public async Task<LiveTvProgram> GetInternalProgram(string id, CancellationToken cancellationToken)
         {
             var guid = new Guid(id);
 
             LiveTvProgram obj = null;
 
             _programs.TryGetValue(guid, out obj);
+
+            if (obj != null)
+            {
+                await RefreshIfNeeded(obj, cancellationToken).ConfigureAwait(false);
+            }
             return obj;
         }
 
+        private async Task RefreshIfNeeded(IEnumerable<LiveTvProgram> programs, CancellationToken cancellationToken)
+        {
+            foreach (var program in programs)
+            {
+                await RefreshIfNeeded(program, cancellationToken).ConfigureAwait(false);
+            }
+        }
+
+        private async Task RefreshIfNeeded(LiveTvProgram program, CancellationToken cancellationToken)
+        {
+            if (_refreshedPrograms.ContainsKey(program.Id))
+            {
+                return;
+            }
+
+            await program.RefreshMetadata(CancellationToken.None).ConfigureAwait(false);
+
+            _refreshedPrograms.TryAdd(program.Id, true);
+        }
+
         public async Task<ILiveTvRecording> GetInternalRecording(string id, CancellationToken cancellationToken)
         {
             var service = ActiveService;
@@ -336,10 +367,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             return item;
         }
 
-        private async Task<LiveTvProgram> GetProgram(ProgramInfo info, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
+        private LiveTvProgram GetProgram(ProgramInfo info, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
         {
-            var isNew = false;
-
             var id = _tvDtoService.GetInternalProgramId(serviceName, info.Id);
 
             var item = _itemRepo.RetrieveItem(id) as LiveTvProgram;
@@ -353,8 +382,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                     DateCreated = DateTime.UtcNow,
                     DateModified = DateTime.UtcNow
                 };
-
-                isNew = true;
             }
 
             item.ChannelType = channelType;
@@ -386,12 +413,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             item.RunTimeTicks = (info.EndDate - info.StartDate).Ticks;
             item.StartDate = info.StartDate;
 
-            await item.RefreshMetadata(new MetadataRefreshOptions
-            {
-                ForceSave = isNew
-
-            }, cancellationToken);
-
             return item;
         }
 
@@ -464,7 +485,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
         public async Task<ProgramInfoDto> GetProgram(string id, CancellationToken cancellationToken, User user = null)
         {
-            var program = GetInternalProgram(id);
+            var program = await GetInternalProgram(id, cancellationToken).ConfigureAwait(false);
 
             var channel = GetChannel(program);
 
@@ -531,7 +552,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 programs = programs.Where(i => i.IsParentalAllowed(currentUser));
             }
 
-            var returnArray = programs
+            var programList = programs.ToList();
+
+            var returnArray = programList
                 .Select(i =>
                 {
                     var channel = GetChannel(i);
@@ -540,6 +563,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 })
                 .ToArray();
 
+            await RefreshIfNeeded(programList, cancellationToken).ConfigureAwait(false);
+
             await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false);
 
             var result = new QueryResult<ProgramInfoDto>
@@ -592,7 +617,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                     .OrderBy(i => i.StartDate);
             }
 
-            var returnArray = programs
+            programList = programs.ToList();
+
+            await RefreshIfNeeded(programList, cancellationToken).ConfigureAwait(false);
+
+            var returnArray = programList
                 .Select(i =>
                 {
                     var channel = GetChannel(i);
@@ -791,8 +820,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
                     var channelPrograms = await service.GetProgramsAsync(currentChannel.ExternalId, start, end, cancellationToken).ConfigureAwait(false);
 
-                    var programTasks = channelPrograms.Select(program => GetProgram(program, currentChannel.ChannelType, service.Name, cancellationToken));
-                    var programEntities = await Task.WhenAll(programTasks).ConfigureAwait(false);
+                    var programEntities = channelPrograms.Select(program => GetProgram(program, currentChannel.ChannelType, service.Name, cancellationToken));
 
                     programs.AddRange(programEntities);
                 }
@@ -813,6 +841,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             }
 
             _programs = programs.ToDictionary(i => i.Id);
+            _refreshedPrograms.Clear();
             progress.Report(90);
 
             // Load these now which will prefetch metadata
@@ -1031,14 +1060,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                     .Where(i => _tvDtoService.GetInternalSeriesTimerId(currentServiceName, i.SeriesTimerId) == guid);
             }
 
-            var returnArray = timers
-                .Select(i =>
-                {
-                    var program = string.IsNullOrEmpty(i.ProgramId) ? null : GetInternalProgram(_tvDtoService.GetInternalProgramId(service.Name, i.ProgramId).ToString("N"));
-                    var channel = string.IsNullOrEmpty(i.ChannelId) ? null : GetInternalChannel(_tvDtoService.GetInternalChannelId(service.Name, i.ChannelId));
+            var returnList = new List<TimerInfoDto>();
 
-                    return _tvDtoService.GetTimerInfoDto(i, service, program, channel);
-                })
+            foreach (var i in timers)
+            {
+                var program = string.IsNullOrEmpty(i.ProgramId) ? 
+                    null :
+                    await GetInternalProgram(_tvDtoService.GetInternalProgramId(service.Name, i.ProgramId).ToString("N"), cancellationToken).ConfigureAwait(false);
+
+                var channel = string.IsNullOrEmpty(i.ChannelId) ? null : GetInternalChannel(_tvDtoService.GetInternalChannelId(service.Name, i.ChannelId));
+
+                returnList.Add(_tvDtoService.GetTimerInfoDto(i, service, program, channel));
+            }
+
+            var returnArray = returnList
                 .OrderBy(i => i.StartDate)
                 .ToArray();
 
@@ -1163,24 +1198,33 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             };
         }
 
-        public Task<ChannelInfoDto> GetChannel(string id, CancellationToken cancellationToken, User user = null)
+        public async Task<ChannelInfoDto> GetChannel(string id, CancellationToken cancellationToken, User user = null)
         {
             var channel = GetInternalChannel(id);
 
-            var dto = _tvDtoService.GetChannelInfoDto(channel, GetCurrentProgram(channel.ExternalId), user);
+            var currentProgram = await GetCurrentProgram(channel.ExternalId, cancellationToken).ConfigureAwait(false);
+
+            var dto = _tvDtoService.GetChannelInfoDto(channel, currentProgram, user);
 
-            return Task.FromResult(dto);
+            return dto;
         }
 
-        private LiveTvProgram GetCurrentProgram(string externalChannelId)
+        private async Task<LiveTvProgram> GetCurrentProgram(string externalChannelId, CancellationToken cancellationToken)
         {
             var now = DateTime.UtcNow;
 
-            return _programs.Values
+            var program = _programs.Values
                 .Where(i => string.Equals(externalChannelId, i.ExternalChannelId, StringComparison.OrdinalIgnoreCase))
                 .OrderBy(i => i.StartDate)
                 .SkipWhile(i => now >= (i.EndDate ?? DateTime.MinValue))
                 .FirstOrDefault();
+
+            if (program != null)
+            {
+                await RefreshIfNeeded(program, cancellationToken).ConfigureAwait(false);
+            }
+
+            return program;
         }
 
         private async Task<SeriesTimerInfo> GetNewTimerDefaultsInternal(CancellationToken cancellationToken, LiveTvProgram program = null)
@@ -1236,7 +1280,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
         public async Task<SeriesTimerInfoDto> GetNewTimerDefaults(string programId, CancellationToken cancellationToken)
         {
-            var program = GetInternalProgram(programId);
+            var program = await GetInternalProgram(programId, cancellationToken).ConfigureAwait(false);
             var programDto = await GetProgram(programId, cancellationToken).ConfigureAwait(false);
 
             var defaults = await GetNewTimerDefaultsInternal(cancellationToken, program).ConfigureAwait(false);

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

@@ -216,7 +216,6 @@
     <Compile Include="Sorting\AirTimeComparer.cs" />
     <Compile Include="Sorting\AlbumArtistComparer.cs" />
     <Compile Include="Sorting\AlbumComparer.cs" />
-    <Compile Include="Sorting\AlbumCountComparer.cs" />
     <Compile Include="Sorting\AlphanumComparator.cs" />
     <Compile Include="Sorting\ArtistComparer.cs" />
     <Compile Include="Sorting\BudgetComparer.cs" />
@@ -224,13 +223,10 @@
     <Compile Include="Sorting\CriticRatingComparer.cs" />
     <Compile Include="Sorting\DateCreatedComparer.cs" />
     <Compile Include="Sorting\DatePlayedComparer.cs" />
-    <Compile Include="Sorting\EpisodeCountComparer.cs" />
     <Compile Include="Sorting\GameSystemComparer.cs" />
     <Compile Include="Sorting\IsFolderComparer.cs" />
     <Compile Include="Sorting\IsUnplayedComparer.cs" />
     <Compile Include="Sorting\MetascoreComparer.cs" />
-    <Compile Include="Sorting\MovieCountComparer.cs" />
-    <Compile Include="Sorting\MusicVideoCountComparer.cs" />
     <Compile Include="Sorting\NameComparer.cs" />
     <Compile Include="Sorting\OfficialRatingComparer.cs" />
     <Compile Include="Sorting\PlayCountComparer.cs" />
@@ -240,16 +236,13 @@
     <Compile Include="Sorting\RandomComparer.cs" />
     <Compile Include="Sorting\RevenueComparer.cs" />
     <Compile Include="Sorting\RuntimeComparer.cs" />
-    <Compile Include="Sorting\SeriesCountComparer.cs" />
     <Compile Include="Sorting\SeriesSortNameComparer.cs" />
-    <Compile Include="Sorting\SongCountComparer.cs" />
     <Compile Include="Sorting\SortNameComparer.cs" />
     <Compile Include="Persistence\SqliteDisplayPreferencesRepository.cs" />
     <Compile Include="Persistence\SqliteItemRepository.cs" />
     <Compile Include="Persistence\SqliteUserDataRepository.cs" />
     <Compile Include="Persistence\SqliteUserRepository.cs" />
     <Compile Include="Sorting\StudioComparer.cs" />
-    <Compile Include="Sorting\TrailerCountComparer.cs" />
     <Compile Include="Sorting\VideoBitRateComparer.cs" />
     <Compile Include="Themes\AppThemeManager.cs" />
     <Compile Include="Udp\UdpMessageReceivedEventArgs.cs" />

+ 0 - 71
MediaBrowser.Server.Implementations/Sorting/AlbumCountComparer.cs

@@ -1,71 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Controller.Sorting;
-using MediaBrowser.Model.Querying;
-
-namespace MediaBrowser.Server.Implementations.Sorting
-{
-    class AlbumCountComparer : IUserBaseItemComparer
-    {
-        /// <summary>
-        /// Gets or sets the user.
-        /// </summary>
-        /// <value>The user.</value>
-        public User User { get; set; }
-
-        /// <summary>
-        /// Gets or sets the user manager.
-        /// </summary>
-        /// <value>The user manager.</value>
-        public IUserManager UserManager { get; set; }
-
-        /// <summary>
-        /// Gets or sets the user data repository.
-        /// </summary>
-        /// <value>The user data repository.</value>
-        public IUserDataManager UserDataRepository { get; set; }
-
-        /// <summary>
-        /// Compares the specified x.
-        /// </summary>
-        /// <param name="x">The x.</param>
-        /// <param name="y">The y.</param>
-        /// <returns>System.Int32.</returns>
-        public int Compare(BaseItem x, BaseItem y)
-        {
-            return GetValue(x).CompareTo(GetValue(y));
-        }
-
-        /// <summary>
-        /// Gets the date.
-        /// </summary>
-        /// <param name="x">The x.</param>
-        /// <returns>DateTime.</returns>
-        private int GetValue(BaseItem x)
-        {
-            var itemByName = x as IItemByName;
-
-            if (itemByName != null)
-            {
-                var counts = itemByName.GetItemByNameCounts(User.Id);
-
-                if (counts != null)
-                {
-                    return counts.AlbumCount;
-                }
-            }
-
-            return 0;
-        }
-
-        /// <summary>
-        /// Gets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public string Name
-        {
-            get { return ItemSortBy.AlbumCount; }
-        }
-    }
-}

+ 0 - 71
MediaBrowser.Server.Implementations/Sorting/EpisodeCountComparer.cs

@@ -1,71 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Controller.Sorting;
-using MediaBrowser.Model.Querying;
-
-namespace MediaBrowser.Server.Implementations.Sorting
-{
-    class EpisodeCountComparer : IUserBaseItemComparer
-    {
-        /// <summary>
-        /// Gets or sets the user.
-        /// </summary>
-        /// <value>The user.</value>
-        public User User { get; set; }
-
-        /// <summary>
-        /// Gets or sets the user manager.
-        /// </summary>
-        /// <value>The user manager.</value>
-        public IUserManager UserManager { get; set; }
-
-        /// <summary>
-        /// Gets or sets the user data repository.
-        /// </summary>
-        /// <value>The user data repository.</value>
-        public IUserDataManager UserDataRepository { get; set; }
-
-        /// <summary>
-        /// Compares the specified x.
-        /// </summary>
-        /// <param name="x">The x.</param>
-        /// <param name="y">The y.</param>
-        /// <returns>System.Int32.</returns>
-        public int Compare(BaseItem x, BaseItem y)
-        {
-            return GetValue(x).CompareTo(GetValue(y));
-        }
-
-        /// <summary>
-        /// Gets the date.
-        /// </summary>
-        /// <param name="x">The x.</param>
-        /// <returns>DateTime.</returns>
-        private int GetValue(BaseItem x)
-        {
-            var itemByName = x as IItemByName;
-
-            if (itemByName != null)
-            {
-                var counts = itemByName.GetItemByNameCounts(User.Id);
-
-                if (counts != null)
-                {
-                    return counts.EpisodeCount;
-                }
-            }
-
-            return 0;
-        }
-
-        /// <summary>
-        /// Gets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public string Name
-        {
-            get { return ItemSortBy.EpisodeCount; }
-        }
-    }
-}

+ 0 - 71
MediaBrowser.Server.Implementations/Sorting/MovieCountComparer.cs

@@ -1,71 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Controller.Sorting;
-using MediaBrowser.Model.Querying;
-
-namespace MediaBrowser.Server.Implementations.Sorting
-{
-    public class MovieCountComparer : IUserBaseItemComparer
-    {
-        /// <summary>
-        /// Gets or sets the user.
-        /// </summary>
-        /// <value>The user.</value>
-        public User User { get; set; }
-
-        /// <summary>
-        /// Gets or sets the user manager.
-        /// </summary>
-        /// <value>The user manager.</value>
-        public IUserManager UserManager { get; set; }
-
-        /// <summary>
-        /// Gets or sets the user data repository.
-        /// </summary>
-        /// <value>The user data repository.</value>
-        public IUserDataManager UserDataRepository { get; set; }
-
-        /// <summary>
-        /// Compares the specified x.
-        /// </summary>
-        /// <param name="x">The x.</param>
-        /// <param name="y">The y.</param>
-        /// <returns>System.Int32.</returns>
-        public int Compare(BaseItem x, BaseItem y)
-        {
-            return GetValue(x).CompareTo(GetValue(y));
-        }
-
-        /// <summary>
-        /// Gets the date.
-        /// </summary>
-        /// <param name="x">The x.</param>
-        /// <returns>DateTime.</returns>
-        private int GetValue(BaseItem x)
-        {
-            var itemByName = x as IItemByName;
-
-            if (itemByName != null)
-            {
-                var counts = itemByName.GetItemByNameCounts(User.Id);
-
-                if (counts != null)
-                {
-                    return counts.MovieCount;
-                }
-            }
-
-            return 0;
-        }
-
-        /// <summary>
-        /// Gets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public string Name
-        {
-            get { return ItemSortBy.MovieCount; }
-        }
-    }
-}

+ 0 - 71
MediaBrowser.Server.Implementations/Sorting/MusicVideoCountComparer.cs

@@ -1,71 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Controller.Sorting;
-using MediaBrowser.Model.Querying;
-
-namespace MediaBrowser.Server.Implementations.Sorting
-{
-    class MusicVideoCountComparer : IUserBaseItemComparer
-    {
-        /// <summary>
-        /// Gets or sets the user.
-        /// </summary>
-        /// <value>The user.</value>
-        public User User { get; set; }
-
-        /// <summary>
-        /// Gets or sets the user manager.
-        /// </summary>
-        /// <value>The user manager.</value>
-        public IUserManager UserManager { get; set; }
-
-        /// <summary>
-        /// Gets or sets the user data repository.
-        /// </summary>
-        /// <value>The user data repository.</value>
-        public IUserDataManager UserDataRepository { get; set; }
-
-        /// <summary>
-        /// Compares the specified x.
-        /// </summary>
-        /// <param name="x">The x.</param>
-        /// <param name="y">The y.</param>
-        /// <returns>System.Int32.</returns>
-        public int Compare(BaseItem x, BaseItem y)
-        {
-            return GetValue(x).CompareTo(GetValue(y));
-        }
-
-        /// <summary>
-        /// Gets the date.
-        /// </summary>
-        /// <param name="x">The x.</param>
-        /// <returns>DateTime.</returns>
-        private int GetValue(BaseItem x)
-        {
-            var itemByName = x as IItemByName;
-
-            if (itemByName != null)
-            {
-                var counts = itemByName.GetItemByNameCounts(User.Id);
-
-                if (counts != null)
-                {
-                    return counts.MusicVideoCount;
-                }
-            }
-
-            return 0;
-        }
-
-        /// <summary>
-        /// Gets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public string Name
-        {
-            get { return ItemSortBy.MusicVideoCount; }
-        }
-    }
-}

+ 0 - 71
MediaBrowser.Server.Implementations/Sorting/SeriesCountComparer.cs

@@ -1,71 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Controller.Sorting;
-using MediaBrowser.Model.Querying;
-
-namespace MediaBrowser.Server.Implementations.Sorting
-{
-    class SeriesCountComparer : IUserBaseItemComparer
-    {
-        /// <summary>
-        /// Gets or sets the user.
-        /// </summary>
-        /// <value>The user.</value>
-        public User User { get; set; }
-
-        /// <summary>
-        /// Gets or sets the user manager.
-        /// </summary>
-        /// <value>The user manager.</value>
-        public IUserManager UserManager { get; set; }
-
-        /// <summary>
-        /// Gets or sets the user data repository.
-        /// </summary>
-        /// <value>The user data repository.</value>
-        public IUserDataManager UserDataRepository { get; set; }
-
-        /// <summary>
-        /// Compares the specified x.
-        /// </summary>
-        /// <param name="x">The x.</param>
-        /// <param name="y">The y.</param>
-        /// <returns>System.Int32.</returns>
-        public int Compare(BaseItem x, BaseItem y)
-        {
-            return GetValue(x).CompareTo(GetValue(y));
-        }
-
-        /// <summary>
-        /// Gets the date.
-        /// </summary>
-        /// <param name="x">The x.</param>
-        /// <returns>DateTime.</returns>
-        private int GetValue(BaseItem x)
-        {
-            var itemByName = x as IItemByName;
-
-            if (itemByName != null)
-            {
-                var counts = itemByName.GetItemByNameCounts(User.Id);
-
-                if (counts != null)
-                {
-                    return counts.SeriesCount;
-                }
-            }
-
-            return 0;
-        }
-
-        /// <summary>
-        /// Gets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public string Name
-        {
-            get { return ItemSortBy.SeriesCount; }
-        }
-    }
-}

+ 0 - 71
MediaBrowser.Server.Implementations/Sorting/SongCountComparer.cs

@@ -1,71 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Controller.Sorting;
-using MediaBrowser.Model.Querying;
-
-namespace MediaBrowser.Server.Implementations.Sorting
-{
-    class SongCountComparer : IUserBaseItemComparer
-    {
-        /// <summary>
-        /// Gets or sets the user.
-        /// </summary>
-        /// <value>The user.</value>
-        public User User { get; set; }
-
-        /// <summary>
-        /// Gets or sets the user manager.
-        /// </summary>
-        /// <value>The user manager.</value>
-        public IUserManager UserManager { get; set; }
-
-        /// <summary>
-        /// Gets or sets the user data repository.
-        /// </summary>
-        /// <value>The user data repository.</value>
-        public IUserDataManager UserDataRepository { get; set; }
-
-        /// <summary>
-        /// Compares the specified x.
-        /// </summary>
-        /// <param name="x">The x.</param>
-        /// <param name="y">The y.</param>
-        /// <returns>System.Int32.</returns>
-        public int Compare(BaseItem x, BaseItem y)
-        {
-            return GetValue(x).CompareTo(GetValue(y));
-        }
-
-        /// <summary>
-        /// Gets the date.
-        /// </summary>
-        /// <param name="x">The x.</param>
-        /// <returns>DateTime.</returns>
-        private int GetValue(BaseItem x)
-        {
-            var itemByName = x as IItemByName;
-
-            if (itemByName != null)
-            {
-                var counts = itemByName.GetItemByNameCounts(User.Id);
-
-                if (counts != null)
-                {
-                    return counts.SongCount;
-                }
-            }
-
-            return 0;
-        }
-
-        /// <summary>
-        /// Gets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public string Name
-        {
-            get { return ItemSortBy.SongCount; }
-        }
-    }
-}

+ 0 - 71
MediaBrowser.Server.Implementations/Sorting/TrailerCountComparer.cs

@@ -1,71 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Controller.Sorting;
-using MediaBrowser.Model.Querying;
-
-namespace MediaBrowser.Server.Implementations.Sorting
-{
-    public class TrailerCountComparer : IUserBaseItemComparer
-    {
-        /// <summary>
-        /// Gets or sets the user.
-        /// </summary>
-        /// <value>The user.</value>
-        public User User { get; set; }
-
-        /// <summary>
-        /// Gets or sets the user manager.
-        /// </summary>
-        /// <value>The user manager.</value>
-        public IUserManager UserManager { get; set; }
-
-        /// <summary>
-        /// Gets or sets the user data repository.
-        /// </summary>
-        /// <value>The user data repository.</value>
-        public IUserDataManager UserDataRepository { get; set; }
-
-        /// <summary>
-        /// Compares the specified x.
-        /// </summary>
-        /// <param name="x">The x.</param>
-        /// <param name="y">The y.</param>
-        /// <returns>System.Int32.</returns>
-        public int Compare(BaseItem x, BaseItem y)
-        {
-            return GetValue(x).CompareTo(GetValue(y));
-        }
-
-        /// <summary>
-        /// Gets the date.
-        /// </summary>
-        /// <param name="x">The x.</param>
-        /// <returns>DateTime.</returns>
-        private int GetValue(BaseItem x)
-        {
-            var itemByName = x as IItemByName;
-
-            if (itemByName != null)
-            {
-                var counts = itemByName.GetItemByNameCounts(User.Id);
-
-                if (counts != null)
-                {
-                    return counts.TrailerCount;
-                }
-            }
-
-            return 0;
-        }
-
-        /// <summary>
-        /// Gets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public string Name
-        {
-            get { return ItemSortBy.TrailerCount; }
-        }
-    }
-}