Explorar o código

added optional SeasonUserData

Luke Pulverenti %!s(int64=10) %!d(string=hai) anos
pai
achega
55b9bffabc
Modificáronse 26 ficheiros con 157 adicións e 192 borrados
  1. 1 11
      MediaBrowser.Api/IHasDtoOptions.cs
  2. 13 28
      MediaBrowser.Api/Library/LibraryService.cs
  3. 4 1
      MediaBrowser.Api/Movies/CollectionService.cs
  4. 16 12
      MediaBrowser.Api/Movies/MoviesService.cs
  5. 9 7
      MediaBrowser.Api/Sync/SyncService.cs
  6. 4 5
      MediaBrowser.Api/UserLibrary/ArtistsService.cs
  7. 3 4
      MediaBrowser.Api/UserLibrary/GameGenresService.cs
  8. 3 4
      MediaBrowser.Api/UserLibrary/GenresService.cs
  9. 3 4
      MediaBrowser.Api/UserLibrary/MusicGenresService.cs
  10. 3 4
      MediaBrowser.Api/UserLibrary/PersonsService.cs
  11. 3 4
      MediaBrowser.Api/UserLibrary/StudiosService.cs
  12. 21 24
      MediaBrowser.Api/UserLibrary/UserLibraryService.cs
  13. 3 4
      MediaBrowser.Api/UserLibrary/YearsService.cs
  14. 3 5
      MediaBrowser.Api/VideosService.cs
  15. 12 2
      MediaBrowser.Controller/Entities/TV/Series.cs
  16. 5 0
      MediaBrowser.Model/Dto/BaseItemDto.cs
  17. 16 1
      MediaBrowser.Model/Dto/DtoOptions.cs
  18. 6 1
      MediaBrowser.Model/Querying/ItemFields.cs
  19. 0 25
      MediaBrowser.Providers/TV/SeriesMetadataService.cs
  20. 0 4
      MediaBrowser.Providers/TV/SeriesPostScanTask.cs
  21. 10 25
      MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
  22. 15 5
      MediaBrowser.Server.Implementations/Dto/DtoService.cs
  23. 1 4
      MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
  24. 1 0
      MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
  25. 1 1
      MediaBrowser.Server.Implementations/Localization/Server/server.json
  26. 1 7
      MediaBrowser.Server.Implementations/Sync/SyncManager.cs

+ 1 - 11
MediaBrowser.Api/IHasDtoOptions.cs

@@ -28,17 +28,7 @@ namespace MediaBrowser.Api
                 options.ImageTypeLimit = request.ImageTypeLimit.Value;
             }
 
-            if (string.IsNullOrWhiteSpace(request.EnableImageTypes))
-            {
-                if (options.EnableImages)
-                {
-                    // Get everything
-                    options.ImageTypes = Enum.GetNames(typeof(ImageType))
-                        .Select(i => (ImageType)Enum.Parse(typeof(ImageType), i, true))
-                        .ToList();
-                }
-            }
-            else
+            if (!string.IsNullOrWhiteSpace(request.EnableImageTypes))
             {
                 options.ImageTypes = (request.EnableImageTypes ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).Select(v => (ImageType)Enum.Parse(typeof(ImageType), v, true)).ToList();
             }

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

@@ -272,16 +272,13 @@ namespace MediaBrowser.Api.Library
                 items = items.Where(i => i.IsHidden == val).ToList();
             }
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields))
-                    .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
-                    .ToList();
+            var dtoOptions = new DtoOptions();
             
             var result = new ItemsResult
             {
                 TotalRecordCount = items.Count,
 
-                Items = items.Select(i => _dtoService.GetBaseItemDto(i, fields)).ToArray()
+                Items = items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions)).ToArray()
             };
 
             return ToOptimizedResult(result);
@@ -347,10 +344,7 @@ namespace MediaBrowser.Api.Library
 
             var user = request.UserId.HasValue ? _userManager.GetUserById(request.UserId.Value) : null;
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields))
-                    .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
-                    .ToList();
+            var dtoOptions = new DtoOptions();
 
             BaseItem parent = item.Parent;
             
@@ -361,7 +355,7 @@ namespace MediaBrowser.Api.Library
                     parent = TranslateParentItem(parent, user);
                 }
 
-                baseItemDtos.Add(_dtoService.GetBaseItemDto(parent, fields, user));
+                baseItemDtos.Add(_dtoService.GetBaseItemDto(parent, dtoOptions, user));
 
                 parent = parent.Parent;
             }
@@ -583,11 +577,6 @@ namespace MediaBrowser.Api.Library
                 item = item.Parent;
             }
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields))
-                    .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
-                    .ToList();
-
             var themeSongIds = GetThemeSongIds(item);
 
             if (themeSongIds.Count == 0 && request.InheritFromParent)
@@ -607,10 +596,12 @@ namespace MediaBrowser.Api.Library
                     }
                 }
             }
-           
+
+            var dtoOptions = new DtoOptions();
+
             var dtos = themeSongIds.Select(_libraryManager.GetItemById)
                             .OrderBy(i => i.SortName)
-                            .Select(i => _dtoService.GetBaseItemDto(i, fields, user, item));
+                            .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
 
             var items = dtos.ToArray();
 
@@ -651,11 +642,6 @@ namespace MediaBrowser.Api.Library
                 item = item.Parent;
             }
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields))
-                    .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
-                    .ToList();
-
             var themeVideoIds = GetThemeVideoIds(item);
 
             if (themeVideoIds.Count == 0 && request.InheritFromParent)
@@ -681,9 +667,11 @@ namespace MediaBrowser.Api.Library
                 }
             }
 
+            var dtoOptions = new DtoOptions();
+
             var dtos = themeVideoIds.Select(_libraryManager.GetItemById)
                             .OrderBy(i => i.SortName)
-                            .Select(i => _dtoService.GetBaseItemDto(i, fields, user, item));
+                            .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
 
             var items = dtos.ToArray();
 
@@ -754,10 +742,7 @@ namespace MediaBrowser.Api.Library
                                   : (Folder)_libraryManager.RootFolder)
                            : _libraryManager.GetItemById(id);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields))
-                    .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
-                    .ToList();
+            var dtoOptions = new DtoOptions();
 
             var dtos = GetSoundtrackSongIds(item, inheritFromParent)
                 .Select(_libraryManager.GetItemById)
@@ -765,7 +750,7 @@ namespace MediaBrowser.Api.Library
                 .SelectMany(i => i.RecursiveChildren)
                 .OfType<Audio>()
                 .OrderBy(i => i.SortName)
-                .Select(i => _dtoService.GetBaseItemDto(i, fields, user, item));
+                .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
 
             var items = dtos.ToArray();
 

+ 4 - 1
MediaBrowser.Api/Movies/CollectionService.cs

@@ -2,6 +2,7 @@
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Collections;
+using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Querying;
 using ServiceStack;
 using System;
@@ -70,7 +71,9 @@ namespace MediaBrowser.Api.Movies
 
             }).ConfigureAwait(false);
 
-            var dto = _dtoService.GetBaseItemDto(item, new List<ItemFields>());
+            var dtoOptions = new DtoOptions();
+
+            var dto = _dtoService.GetBaseItemDto(item, dtoOptions);
 
             return ToOptimizedResult(new CollectionCreationResult
             {

+ 16 - 12
MediaBrowser.Api/Movies/MoviesService.cs

@@ -157,7 +157,11 @@ namespace MediaBrowser.Api.Movies
                 .DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString(), StringComparer.OrdinalIgnoreCase)
                 .ToList();
 
-            var result = GetRecommendationCategories(user, listEligibleForCategories, listEligibleForSuggestion, request.CategoryLimit, request.ItemLimit, request.GetItemFields().ToList());
+            var dtoOptions = new DtoOptions();
+
+            dtoOptions.Fields = request.GetItemFields().ToList();
+            
+            var result = GetRecommendationCategories(user, listEligibleForCategories, listEligibleForSuggestion, request.CategoryLimit, request.ItemLimit, dtoOptions);
 
             return ToOptimizedResult(result);
         }
@@ -232,7 +236,7 @@ namespace MediaBrowser.Api.Movies
             return result;
         }
 
-        private IEnumerable<RecommendationDto> GetRecommendationCategories(User user, List<BaseItem> allMoviesForCategories, List<BaseItem> allMovies, int categoryLimit, int itemLimit, List<ItemFields> fields)
+        private IEnumerable<RecommendationDto> GetRecommendationCategories(User user, List<BaseItem> allMoviesForCategories, List<BaseItem> allMovies, int categoryLimit, int itemLimit, DtoOptions dtoOptions)
         {
             var categories = new List<RecommendationDto>();
 
@@ -282,11 +286,11 @@ namespace MediaBrowser.Api.Movies
                 .OrderBy(i => Guid.NewGuid())
                 .ToList();
 
-            var similarToRecentlyPlayed = GetSimilarTo(user, allMovies, recentlyPlayedMovies.Take(7).OrderBy(i => Guid.NewGuid()), itemLimit, fields, RecommendationType.SimilarToRecentlyPlayed).GetEnumerator();
-            var similarToLiked = GetSimilarTo(user, allMovies, likedMovies, itemLimit, fields, RecommendationType.SimilarToLikedItem).GetEnumerator();
+            var similarToRecentlyPlayed = GetSimilarTo(user, allMovies, recentlyPlayedMovies.Take(7).OrderBy(i => Guid.NewGuid()), itemLimit, dtoOptions, RecommendationType.SimilarToRecentlyPlayed).GetEnumerator();
+            var similarToLiked = GetSimilarTo(user, allMovies, likedMovies, itemLimit, dtoOptions, RecommendationType.SimilarToLikedItem).GetEnumerator();
 
-            var hasDirectorFromRecentlyPlayed = GetWithDirector(user, allMovies, recentDirectors, itemLimit, fields, RecommendationType.HasDirectorFromRecentlyPlayed).GetEnumerator();
-            var hasActorFromRecentlyPlayed = GetWithActor(user, allMovies, recentActors, itemLimit, fields, RecommendationType.HasActorFromRecentlyPlayed).GetEnumerator();
+            var hasDirectorFromRecentlyPlayed = GetWithDirector(user, allMovies, recentDirectors, itemLimit, dtoOptions, RecommendationType.HasDirectorFromRecentlyPlayed).GetEnumerator();
+            var hasActorFromRecentlyPlayed = GetWithActor(user, allMovies, recentActors, itemLimit, dtoOptions, RecommendationType.HasActorFromRecentlyPlayed).GetEnumerator();
 
             var categoryTypes = new List<IEnumerator<RecommendationDto>>
             {
@@ -329,7 +333,7 @@ namespace MediaBrowser.Api.Movies
             return categories.OrderBy(i => i.RecommendationType).ThenBy(i => Guid.NewGuid());
         }
 
-        private IEnumerable<RecommendationDto> GetWithDirector(User user, List<BaseItem> allMovies, IEnumerable<string> directors, int itemLimit, List<ItemFields> fields, RecommendationType type)
+        private IEnumerable<RecommendationDto> GetWithDirector(User user, List<BaseItem> allMovies, IEnumerable<string> directors, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
         {
             var userId = user.Id;
 
@@ -347,13 +351,13 @@ namespace MediaBrowser.Api.Movies
                         BaselineItemName = director,
                         CategoryId = director.GetMD5().ToString("N"),
                         RecommendationType = type,
-                        Items = items.Select(i => _dtoService.GetBaseItemDto(i, fields, user)).ToArray()
+                        Items = items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user)).ToArray()
                     };
                 }
             }
         }
 
-        private IEnumerable<RecommendationDto> GetWithActor(User user, List<BaseItem> allMovies, IEnumerable<string> names, int itemLimit, List<ItemFields> fields, RecommendationType type)
+        private IEnumerable<RecommendationDto> GetWithActor(User user, List<BaseItem> allMovies, IEnumerable<string> names, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
         {
             var userId = user.Id;
 
@@ -371,13 +375,13 @@ namespace MediaBrowser.Api.Movies
                         BaselineItemName = name,
                         CategoryId = name.GetMD5().ToString("N"),
                         RecommendationType = type,
-                        Items = items.Select(i => _dtoService.GetBaseItemDto(i, fields, user)).ToArray()
+                        Items = items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user)).ToArray()
                     };
                 }
             }
         }
 
-        private IEnumerable<RecommendationDto> GetSimilarTo(User user, List<BaseItem> allMovies, IEnumerable<BaseItem> baselineItems, int itemLimit, List<ItemFields> fields, RecommendationType type)
+        private IEnumerable<RecommendationDto> GetSimilarTo(User user, List<BaseItem> allMovies, IEnumerable<BaseItem> baselineItems, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
         {
             var userId = user.Id;
 
@@ -395,7 +399,7 @@ namespace MediaBrowser.Api.Movies
                         BaselineItemName = item.Name,
                         CategoryId = item.Id.ToString("N"),
                         RecommendationType = type,
-                        Items = similar.Select(i => _dtoService.GetBaseItemDto(i, fields, user)).ToArray()
+                        Items = similar.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user)).ToArray()
                     };
                 }
             }

+ 9 - 7
MediaBrowser.Api/Sync/SyncService.cs

@@ -173,16 +173,18 @@ namespace MediaBrowser.Api.Sync
             }
             else
             {
+                var dtoOptions = new DtoOptions
+                {
+                    Fields = new List<ItemFields>
+                    {
+                        ItemFields.SyncInfo
+                    }
+                };
+
                 var dtos = request.ItemIds.Split(',')
                     .Select(_libraryManager.GetItemById)
                     .Where(i => i != null)
-                    .Select(i => _dtoService.GetBaseItemDto(i, new DtoOptions
-                    {
-                        Fields = new List<ItemFields>
-                        {
-                            ItemFields.SyncInfo
-                        }
-                    }))
+                    .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions))
                     .ToList();
 
                 result.Options = SyncHelper.GetSyncOptions(dtos);

+ 4 - 5
MediaBrowser.Api/UserLibrary/ArtistsService.cs

@@ -83,17 +83,16 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var item = GetArtist(request.Name, LibraryManager);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
+            var dtoOptions = new DtoOptions();
 
             if (request.UserId.HasValue)
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
-                
-                return DtoService.GetBaseItemDto(item, fields.ToList(), user);
+
+                return DtoService.GetBaseItemDto(item, dtoOptions, user);
             }
 
-            return DtoService.GetBaseItemDto(item, fields.ToList());
+            return DtoService.GetBaseItemDto(item, dtoOptions);
         }
 
         /// <summary>

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

@@ -69,17 +69,16 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var item = GetGameGenre(request.Name, LibraryManager);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
+            var dtoOptions = new DtoOptions();
 
             if (request.UserId.HasValue)
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
 
-                return DtoService.GetBaseItemDto(item, fields.ToList(), user);
+                return DtoService.GetBaseItemDto(item, dtoOptions, user);
             }
 
-            return DtoService.GetBaseItemDto(item, fields.ToList());
+            return DtoService.GetBaseItemDto(item, dtoOptions);
         }
 
         /// <summary>

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

@@ -74,17 +74,16 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var item = GetGenre(request.Name, LibraryManager);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
+            var dtoOptions = new DtoOptions();
 
             if (request.UserId.HasValue)
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
 
-                return DtoService.GetBaseItemDto(item, fields.ToList(), user);
+                return DtoService.GetBaseItemDto(item, dtoOptions, user);
             }
 
-            return DtoService.GetBaseItemDto(item, fields.ToList());
+            return DtoService.GetBaseItemDto(item, dtoOptions);
         }
 
         /// <summary>

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

@@ -69,17 +69,16 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var item = GetMusicGenre(request.Name, LibraryManager);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
+            var dtoOptions = new DtoOptions();
 
             if (request.UserId.HasValue)
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
 
-                return DtoService.GetBaseItemDto(item, fields.ToList(), user);
+                return DtoService.GetBaseItemDto(item, dtoOptions, user);
             }
 
-            return DtoService.GetBaseItemDto(item, fields.ToList());
+            return DtoService.GetBaseItemDto(item, dtoOptions);
         }
 
         /// <summary>

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

@@ -86,17 +86,16 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var item = GetPerson(request.Name, LibraryManager);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
+            var dtoOptions = new DtoOptions();
 
             if (request.UserId.HasValue)
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
 
-                return DtoService.GetBaseItemDto(item, fields.ToList(), user);
+                return DtoService.GetBaseItemDto(item, dtoOptions, user);
             }
 
-            return DtoService.GetBaseItemDto(item, fields.ToList());
+            return DtoService.GetBaseItemDto(item, dtoOptions);
         }
 
         /// <summary>

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

@@ -73,17 +73,16 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var item = GetStudio(request.Name, LibraryManager);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
+            var dtoOptions = new DtoOptions();
 
             if (request.UserId.HasValue)
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
 
-                return DtoService.GetBaseItemDto(item, fields.ToList(), user);
+                return DtoService.GetBaseItemDto(item, dtoOptions, user);
             }
 
-            return DtoService.GetBaseItemDto(item, fields.ToList());
+            return DtoService.GetBaseItemDto(item, dtoOptions);
         }
 
         /// <summary>

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

@@ -407,9 +407,6 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var user = _userManager.GetUserById(request.UserId);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
-
             var query = new UserViewQuery
             {
                 UserId = request.UserId
@@ -423,7 +420,9 @@ namespace MediaBrowser.Api.UserLibrary
 
             var folders = await _userViewManager.GetUserViews(query, CancellationToken.None).ConfigureAwait(false);
 
-            var dtos = folders.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
+            var dtoOptions = new DtoOptions();
+
+            var dtos = folders.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user))
                 .ToArray();
 
             var result = new QueryResult<BaseItemDto>
@@ -443,14 +442,16 @@ namespace MediaBrowser.Api.UserLibrary
                 user.RootFolder :
                 _libraryManager.GetItemById(request.Id);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
-
             var series = item as Series;
 
             // Get them from the child tree
             if (series != null)
             {
+                var dtoOptions = new DtoOptions();
+
+                // Avoid implicitly captured closure
+                var currentUser = user;
+
                 var dtos = series
                     .GetRecursiveChildren()
                     .Where(i => i is Episode && i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
@@ -468,7 +469,7 @@ namespace MediaBrowser.Api.UserLibrary
                         return DateTime.MinValue;
                     })
                     .ThenBy(i => i.SortName)
-                    .Select(i => _dtoService.GetBaseItemDto(i, fields, user));
+                    .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, currentUser));
 
                 return dtos.ToList();
             }
@@ -478,10 +479,12 @@ namespace MediaBrowser.Api.UserLibrary
             // Get them from the db
             if (movie != null)
             {
+                var dtoOptions = new DtoOptions();
+
                 var dtos = movie.SpecialFeatureIds
                     .Select(_libraryManager.GetItemById)
                     .OrderBy(i => i.SortName)
-                    .Select(i => _dtoService.GetBaseItemDto(i, fields, user, item));
+                    .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
 
                 return dtos.ToList();
             }
@@ -507,9 +510,6 @@ namespace MediaBrowser.Api.UserLibrary
 
             var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _libraryManager.GetItemById(request.Id);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
-
             var trailerIds = new List<Guid>();
 
             var hasTrailers = item as IHasTrailers;
@@ -518,10 +518,12 @@ namespace MediaBrowser.Api.UserLibrary
                 trailerIds = hasTrailers.GetTrailerIds();
             }
 
+            var dtoOptions = new DtoOptions();
+
             var dtos = trailerIds
                 .Select(_libraryManager.GetItemById)
                 .OrderBy(i => i.SortName)
-                .Select(i => _dtoService.GetBaseItemDto(i, fields, user, item));
+                .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
 
             return dtos.ToList();
         }
@@ -537,10 +539,9 @@ namespace MediaBrowser.Api.UserLibrary
 
             var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _libraryManager.GetItemById(request.Id);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
+            var dtoOptions = new DtoOptions();
 
-            var result = _dtoService.GetBaseItemDto(item, fields, user);
+            var result = _dtoService.GetBaseItemDto(item, dtoOptions, user);
 
             return ToOptimizedSerializedResultUsingCache(result);
         }
@@ -556,10 +557,9 @@ namespace MediaBrowser.Api.UserLibrary
 
             var item = user.RootFolder;
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
+            var dtoOptions = new DtoOptions();
 
-            var result = _dtoService.GetBaseItemDto(item, fields, user);
+            var result = _dtoService.GetBaseItemDto(item, dtoOptions, user);
 
             return ToOptimizedSerializedResultUsingCache(result);
         }
@@ -577,12 +577,9 @@ namespace MediaBrowser.Api.UserLibrary
 
             var items = await _libraryManager.GetIntros(item, user).ConfigureAwait(false);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields))
-                .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
-                .ToList();
+            var dtoOptions = new DtoOptions();
 
-            var dtos = items.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
+            var dtos = items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user))
                 .ToArray();
 
             var result = new ItemsResult

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

@@ -73,17 +73,16 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var item = LibraryManager.GetYear(request.Year);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
+            var dtoOptions = new DtoOptions();
 
             if (request.UserId.HasValue)
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
 
-                return DtoService.GetBaseItemDto(item, fields.ToList(), user);
+                return DtoService.GetBaseItemDto(item, dtoOptions, user);
             }
 
-            return DtoService.GetBaseItemDto(item, fields.ToList());
+            return DtoService.GetBaseItemDto(item, dtoOptions);
         }
 
         /// <summary>

+ 3 - 5
MediaBrowser.Api/VideosService.cs

@@ -5,6 +5,7 @@ using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Querying;
 using ServiceStack;
 using System;
@@ -79,15 +80,12 @@ namespace MediaBrowser.Api
                                   : _libraryManager.RootFolder)
                            : _libraryManager.GetItemById(request.Id);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields))
-                    .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
-                    .ToList();
+            var dtoOptions = new DtoOptions();
 
             var video = (Video)item;
 
             var items = video.GetAdditionalParts()
-                         .Select(i => _dtoService.GetBaseItemDto(i, fields, user, video))
+                         .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, video))
                          .ToArray();
 
             var result = new ItemsResult

+ 12 - 2
MediaBrowser.Controller/Entities/TV/Series.cs

@@ -3,11 +3,11 @@ using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Querying;
+using MediaBrowser.Model.Users;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Runtime.Serialization;
-using MediaBrowser.Model.Users;
 
 namespace MediaBrowser.Controller.Entities.TV
 {
@@ -88,7 +88,17 @@ namespace MediaBrowser.Controller.Entities.TV
         /// Gets or sets the date last episode added.
         /// </summary>
         /// <value>The date last episode added.</value>
-        public DateTime DateLastEpisodeAdded { get; set; }
+        [IgnoreDataMember]
+        public DateTime DateLastEpisodeAdded
+        {
+            get
+            {
+                return RecursiveChildren.OfType<Episode>()
+                        .Select(i => i.DateCreated)
+                        .OrderByDescending(i => i)
+                        .FirstOrDefault();
+            }
+        }
 
         /// <summary>
         /// Series aren't included directly in indices - Their Episodes will roll up to them

+ 5 - 0
MediaBrowser.Model/Dto/BaseItemDto.cs

@@ -366,6 +366,11 @@ namespace MediaBrowser.Model.Dto
         /// </summary>
         /// <value>The user data.</value>
         public UserItemDataDto UserData { get; set; }
+        /// <summary>
+        /// Gets or sets the season user data.
+        /// </summary>
+        /// <value>The season user data.</value>
+        public UserItemDataDto SeasonUserData { get; set; }
 
         /// <summary>
         /// Gets or sets the recursive item count.

+ 16 - 1
MediaBrowser.Model/Dto/DtoOptions.cs

@@ -1,11 +1,18 @@
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Querying;
+using System;
 using System.Collections.Generic;
+using System.Linq;
 
 namespace MediaBrowser.Model.Dto
 {
     public class DtoOptions
     {
+        private static readonly List<ItemFields> DefaultExcludedFields = new List<ItemFields>
+        {
+            ItemFields.SeasonUserData
+        };
+
         public List<ItemFields> Fields { get; set; }
         public List<ImageType> ImageTypes { get; set; }
         public int ImageTypeLimit { get; set; }
@@ -14,9 +21,17 @@ namespace MediaBrowser.Model.Dto
         public DtoOptions()
         {
             Fields = new List<ItemFields>();
-            ImageTypes = new List<ImageType>();
             ImageTypeLimit = int.MaxValue;
             EnableImages = true;
+
+            Fields = Enum.GetNames(typeof (ItemFields))
+                    .Select(i => (ItemFields) Enum.Parse(typeof (ItemFields), i, true))
+                    .Except(DefaultExcludedFields)
+                    .ToList();
+
+            ImageTypes = Enum.GetNames(typeof(ImageType))
+                .Select(i => (ImageType)Enum.Parse(typeof(ImageType), i, true))
+                .ToList();
         }
 
         public int GetImageLimit(ImageType type)

+ 6 - 1
MediaBrowser.Model/Querying/ItemFields.cs

@@ -234,6 +234,11 @@ namespace MediaBrowser.Model.Querying
         /// <summary>
         /// The media streams
         /// </summary>
-        MediaStreams
+        MediaStreams,
+
+        /// <summary>
+        /// The season user data
+        /// </summary>
+        SeasonUserData
     }
 }

+ 0 - 25
MediaBrowser.Providers/TV/SeriesMetadataService.cs

@@ -7,7 +7,6 @@ using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Providers.Manager;
 using System.Collections.Generic;
-using System.Linq;
 
 namespace MediaBrowser.Providers.TV
 {
@@ -54,29 +53,5 @@ namespace MediaBrowser.Providers.TV
                 target.DisplaySpecialsWithSeasons = source.DisplaySpecialsWithSeasons;
             }
         }
-
-        protected override ItemUpdateType BeforeSave(Series item)
-        {
-            var updateType = base.BeforeSave(item);
-
-            var episodes = item.RecursiveChildren
-                .OfType<Episode>()
-                .ToList();
-
-            var dateLastEpisodeAdded = item.DateLastEpisodeAdded;
-
-            item.DateLastEpisodeAdded = episodes
-                .Where(i => i.LocationType != LocationType.Virtual)
-                .Select(i => i.DateCreated)
-                .OrderByDescending(i => i)
-                .FirstOrDefault();
-
-            if (dateLastEpisodeAdded != item.DateLastEpisodeAdded)
-            {
-                updateType = updateType | ItemUpdateType.MetadataImport;
-            }
-
-            return updateType;
-        }
     }
 }

+ 0 - 4
MediaBrowser.Providers/TV/SeriesPostScanTask.cs

@@ -76,10 +76,6 @@ namespace MediaBrowser.Providers.TV
                     .Select(i => i.Id)
                     .ToList();
 
-                series.DateLastEpisodeAdded = physicalEpisodes.Select(i => i.DateCreated)
-                    .OrderByDescending(i => i)
-                    .FirstOrDefault();
-
                 numComplete++;
                 double percent = numComplete;
                 percent /= seriesList.Count;

+ 10 - 25
MediaBrowser.Server.Implementations/Channels/ChannelManager.cs

@@ -179,12 +179,9 @@ namespace MediaBrowser.Server.Implementations.Channels
 
             var internalResult = await GetChannelsInternal(query, cancellationToken).ConfigureAwait(false);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields))
-                    .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
-                    .ToList();
+            var dtoOptions = new DtoOptions();
 
-            var returnItems = internalResult.Items.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
+            var returnItems = internalResult.Items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user))
                 .ToArray();
 
             var result = new QueryResult<BaseItemDto>
@@ -544,11 +541,6 @@ namespace MediaBrowser.Server.Implementations.Channels
 
             var internalResult = await GetLatestChannelItemsInternal(query, cancellationToken).ConfigureAwait(false);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields))
-                    .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
-                    .ToList();
-
             var items = internalResult.Items;
             var totalRecordCount = internalResult.TotalRecordCount;
 
@@ -563,7 +555,9 @@ namespace MediaBrowser.Server.Implementations.Channels
                 totalRecordCount = items.Length;
             }
 
-            var returnItems = items.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
+            var dtoOptions = new DtoOptions();
+
+            var returnItems = items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user))
                 .ToArray();
 
             var result = new QueryResult<BaseItemDto>
@@ -828,12 +822,9 @@ namespace MediaBrowser.Server.Implementations.Channels
 
             await RefreshIfNeeded(internalResult.Items, new Progress<double>(), cancellationToken).ConfigureAwait(false);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields))
-                    .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
-                    .ToList();
+            var dtoOptions = new DtoOptions();
 
-            var returnItems = internalResult.Items.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
+            var returnItems = internalResult.Items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user))
                 .ToArray();
 
             var result = new QueryResult<BaseItemDto>
@@ -980,12 +971,9 @@ namespace MediaBrowser.Server.Implementations.Channels
 
             var internalResult = await GetChannelItemsInternal(query, new Progress<double>(), cancellationToken).ConfigureAwait(false);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields))
-                    .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
-                    .ToList();
+            var dtoOptions = new DtoOptions();
 
-            var returnItems = internalResult.Items.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
+            var returnItems = internalResult.Items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user))
                 .ToArray();
 
             var result = new QueryResult<BaseItemDto>
@@ -1407,12 +1395,9 @@ namespace MediaBrowser.Server.Implementations.Channels
         {
             var user = string.IsNullOrEmpty(userId) ? null : _userManager.GetUserById(userId);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
-
             var folder = await GetInternalChannelFolder(userId, cancellationToken).ConfigureAwait(false);
 
-            return _dtoService.GetBaseItemDto(folder, fields, user);
+            return _dtoService.GetBaseItemDto(folder, new DtoOptions(), user);
         }
 
         public async Task<Folder> GetInternalChannelFolder(string userId, CancellationToken cancellationToken)

+ 15 - 5
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -73,11 +73,6 @@ namespace MediaBrowser.Server.Implementations.Dto
             {
                 Fields = fields
             };
-
-            // Get everything
-            options.ImageTypes = Enum.GetNames(typeof(ImageType))
-                .Select(i => (ImageType)Enum.Parse(typeof(ImageType), i, true))
-                .ToList();
             
             return GetBaseItemDto(item, options, user, owner);
         }
@@ -273,6 +268,21 @@ namespace MediaBrowser.Server.Implementations.Dto
             }
 
             dto.PlayAccess = item.GetPlayAccess(user);
+
+            if (fields.Contains(ItemFields.SeasonUserData))
+            {
+                var episode = item as Episode;
+
+                if (episode != null)
+                {
+                    var season = episode.Season;
+
+                    if (season != null)
+                    {
+                        dto.SeasonUserData = _userDataRepository.GetUserDataDto(season, user);
+                    }
+                }
+            }
         }
 
         private int GetChildCount(Folder folder, User user)

+ 1 - 4
MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -1872,12 +1872,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
         {
             var user = string.IsNullOrEmpty(userId) ? null : _userManager.GetUserById(userId);
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
-
             var folder = await GetInternalLiveTvFolder(userId, cancellationToken).ConfigureAwait(false);
 
-            return _dtoService.GetBaseItemDto(folder, fields, user);
+            return _dtoService.GetBaseItemDto(folder, new DtoOptions(), user);
         }
 
         public async Task<Folder> GetInternalLiveTvFolder(string userId, CancellationToken cancellationToken)

+ 1 - 0
MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json

@@ -597,6 +597,7 @@
     "WebClientTourMobile2": "and easily controls other devices and Media Browser apps",
     "MessageEnjoyYourStay": "Enjoy your stay",
     "DashboardTourDashboard": "The server dashboard allows you to monitor your server and your users. You'll always know who is doing what and where they are.",
+    "DashboardTourHelp": "In-app help provides easy buttons to open wiki pages relating to the on-screen content.",
     "DashboardTourUsers": "Easily create user accounts for your friends and family, each with their own permissions, library access, parental controls and more.",
     "DashboardTourCinemaMode": "Cinema mode brings the theater experience straight to your living room with the ability to play trailers and custom intros before the main feature.",
     "DashboardTourChapters": "Enable chapter image generation for your videos for a more pleasing presentation while viewing.",

+ 1 - 1
MediaBrowser.Server.Implementations/Localization/Server/server.json

@@ -1273,7 +1273,7 @@
     "HeaderTrailerReel": "Trailer Reel",
     "OptionPlayUnwatchedTrailersOnly": "Play only unwatched trailers",
     "HeaderTrailerReelHelp": "Start a trailer reel to play a long running playlist of trailers.",
-    "MessageNoTrailersFound": "No trailers found. Install the Trailer channel plugin to import a library of internet trailers.",
+    "MessageNoTrailersFound": "No trailers found. Install the Trailer channel to enhance your movie experience by adding a library of internet trailers.",
     "HeaderNewUsers": "New Users",
     "ButtonSignUp": "Sign up",
     "ButtonForgotPassword": "Forgot password?",

+ 1 - 7
MediaBrowser.Server.Implementations/Sync/SyncManager.cs

@@ -332,13 +332,7 @@ namespace MediaBrowser.Server.Implementations.Sync
                 UserId = job.UserId
             };
 
-            // Get everything
-            var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
-
-            syncedItem.Item = _dtoService.GetBaseItemDto(libraryItem, new DtoOptions
-            {
-                Fields = fields
-            });
+            syncedItem.Item = _dtoService.GetBaseItemDto(libraryItem, new DtoOptions());
 
             // TODO: this should be the media source of the transcoded output
             syncedItem.Item.MediaSources = syncedItem.Item.MediaSources