Browse Source

use conditional caching on some json responses

Luke Pulverenti 11 năm trước cách đây
mục cha
commit
351cfef7a7
48 tập tin đã thay đổi với 216 bổ sung138 xóa
  1. 1 1
      MediaBrowser.Api/AlbumsService.cs
  2. 16 5
      MediaBrowser.Api/BaseApiService.cs
  3. 2 2
      MediaBrowser.Api/ConfigurationService.cs
  4. 4 4
      MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs
  5. 1 1
      MediaBrowser.Api/DisplayPreferencesService.cs
  6. 5 5
      MediaBrowser.Api/EnvironmentService.cs
  7. 3 3
      MediaBrowser.Api/GamesService.cs
  8. 2 2
      MediaBrowser.Api/Images/ImageService.cs
  9. 3 3
      MediaBrowser.Api/Images/RemoteImageService.cs
  10. 4 4
      MediaBrowser.Api/InstantMixService.cs
  11. 1 1
      MediaBrowser.Api/Library/FileOrganizationService.cs
  12. 2 2
      MediaBrowser.Api/Library/LibraryService.cs
  13. 2 2
      MediaBrowser.Api/Library/LibraryStructureService.cs
  14. 8 8
      MediaBrowser.Api/LibraryService.cs
  15. 16 16
      MediaBrowser.Api/LiveTv/LiveTvService.cs
  16. 3 3
      MediaBrowser.Api/LocalizationService.cs
  17. 1 1
      MediaBrowser.Api/MoviesService.cs
  18. 1 1
      MediaBrowser.Api/NewsService.cs
  19. 2 2
      MediaBrowser.Api/PluginService.cs
  20. 1 1
      MediaBrowser.Api/SearchService.cs
  21. 1 1
      MediaBrowser.Api/TrailersService.cs
  22. 2 2
      MediaBrowser.Api/TvShowsService.cs
  23. 2 2
      MediaBrowser.Api/UserLibrary/GameGenresService.cs
  24. 2 2
      MediaBrowser.Api/UserLibrary/GenresService.cs
  25. 1 1
      MediaBrowser.Api/UserLibrary/ItemsService.cs
  26. 2 2
      MediaBrowser.Api/UserLibrary/MusicGenresService.cs
  27. 2 2
      MediaBrowser.Api/UserLibrary/PersonsService.cs
  28. 2 2
      MediaBrowser.Api/UserLibrary/StudiosService.cs
  29. 8 6
      MediaBrowser.Api/UserLibrary/UserLibraryService.cs
  30. 2 2
      MediaBrowser.Api/UserLibrary/YearsService.cs
  31. 2 2
      MediaBrowser.Api/UserService.cs
  32. 1 1
      MediaBrowser.Api/VideosService.cs
  33. 9 0
      MediaBrowser.Controller/Entities/BaseItem.cs
  34. 2 2
      MediaBrowser.Controller/Entities/CollectionFolder.cs
  35. 1 1
      MediaBrowser.Controller/Entities/Folder.cs
  36. 12 2
      MediaBrowser.Controller/Net/IHttpResultFactory.cs
  37. 2 4
      MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs
  38. 2 2
      MediaBrowser.Providers/CollectionFolderImageProvider.cs
  39. 7 6
      MediaBrowser.Providers/Manager/MetadataService.cs
  40. 2 2
      MediaBrowser.Providers/Music/AlbumMetadataService.cs
  41. 2 2
      MediaBrowser.Providers/Music/ArtistMetadataService.cs
  42. 2 2
      MediaBrowser.Providers/TV/SeriesMetadataService.cs
  43. 40 5
      MediaBrowser.Providers/TV/TvdbSeriesProvider.cs
  44. 1 1
      MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
  45. 22 12
      MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs
  46. 1 2
      MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
  47. 5 2
      MediaBrowser.Server.Implementations/Library/LibraryManager.cs
  48. 1 1
      MediaBrowser.ServerApplication/ApplicationHost.cs

+ 1 - 1
MediaBrowser.Api/AlbumsService.cs

@@ -59,7 +59,7 @@ namespace MediaBrowser.Api
                 request, item => item is MusicAlbum,
                 GetAlbumSimilarityScore);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

+ 16 - 5
MediaBrowser.Api/BaseApiService.cs

@@ -21,7 +21,7 @@ namespace MediaBrowser.Api
         /// </summary>
         /// <value>The logger.</value>
         public ILogger Logger { get; set; }
-
+        
         /// <summary>
         /// Gets or sets the HTTP result factory.
         /// </summary>
@@ -58,15 +58,26 @@ namespace MediaBrowser.Api
         /// <param name="cacheKey">The cache key.</param>
         /// <param name="lastDateModified">The last date modified.</param>
         /// <param name="cacheDuration">Duration of the cache.</param>
-        /// <param name="factoryFn">The factory fn.</param>
+        /// <param name="factoryFn">The factory function.</param>
         /// <returns>System.Object.</returns>
-        /// <exception cref="System.ArgumentNullException">cacheKey</exception>
-        protected object ToOptimizedResultUsingCache<T>(Guid cacheKey, DateTime lastDateModified, TimeSpan? cacheDuration, Func<T> factoryFn)
-               where T : class
+        protected object ToOptimizedResultUsingCache<T>(Guid cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration, Func<T> factoryFn)
+           where T : class
         {
             return ResultFactory.GetOptimizedResultUsingCache(Request, cacheKey, lastDateModified, cacheDuration, factoryFn);
         }
 
+        /// <summary>
+        /// To the optimized serialized result using cache.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="result">The result.</param>
+        /// <returns>System.Object.</returns>
+        protected object ToOptimizedSerializedResultUsingCache<T>(T result)
+           where T : class
+        {
+            return ResultFactory.GetOptimizedSerializedResultUsingCache(Request, result);
+        }
+        
         /// <summary>
         /// To the cached result.
         /// </summary>

+ 2 - 2
MediaBrowser.Api/ConfigurationService.cs

@@ -99,12 +99,12 @@ namespace MediaBrowser.Api
 
         public object Get(GetDefaultMetadataOptions request)
         {
-            return ToOptimizedResult(new MetadataOptions());
+            return ToOptimizedSerializedResultUsingCache(new MetadataOptions());
         }
 
         public object Get(GetMetadataPlugins request)
         {
-            return ToOptimizedResult(_providerManager.GetAllMetadataPlugins().ToList());
+            return ToOptimizedSerializedResultUsingCache(_providerManager.GetAllMetadataPlugins().ToList());
         }
     }
 }

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

@@ -215,7 +215,7 @@ namespace MediaBrowser.Api.DefaultTheme
                 .Select(i => _dtoService.GetBaseItemDto(i, fields, user))
                 .ToList();
 
-            return ToOptimizedResult(view);
+            return ToOptimizedSerializedResultUsingCache(view);
         }
 
         public object Get(GetGamesView request)
@@ -268,7 +268,7 @@ namespace MediaBrowser.Api.DefaultTheme
             .Take(1)
             .ToList();
 
-            return ToOptimizedResult(view);
+            return ToOptimizedSerializedResultUsingCache(view);
         }
 
         public object Get(GetTvView request)
@@ -394,7 +394,7 @@ namespace MediaBrowser.Api.DefaultTheme
                 .Select(i => _dtoService.GetBaseItemDto(i, fields, user))
                 .ToList();
 
-            return ToOptimizedResult(view);
+            return ToOptimizedSerializedResultUsingCache(view);
         }
 
         public object Get(GetMovieView request)
@@ -569,7 +569,7 @@ namespace MediaBrowser.Api.DefaultTheme
                 .Select(i => _dtoService.GetBaseItemDto(i, fields, user))
                 .ToList();
 
-            return ToOptimizedResult(view);
+            return ToOptimizedSerializedResultUsingCache(view);
         }
 
         private IEnumerable<BaseItem> FilterItemsForBackdropDisplay(IEnumerable<BaseItem> items)

+ 1 - 1
MediaBrowser.Api/DisplayPreferencesService.cs

@@ -88,7 +88,7 @@ namespace MediaBrowser.Api
 
             var result = _displayPreferencesManager.GetDisplayPreferences(displayPreferencesId, request.UserId, request.Client);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

+ 5 - 5
MediaBrowser.Api/EnvironmentService.cs

@@ -135,10 +135,10 @@ namespace MediaBrowser.Api
 
             if (path.StartsWith(networkPrefix, StringComparison.OrdinalIgnoreCase) && path.LastIndexOf(UncSeparator) == 1)
             {
-                return ToOptimizedResult(GetNetworkShares(path).OrderBy(i => i.Path).ToList());
+                return ToOptimizedSerializedResultUsingCache(GetNetworkShares(path).OrderBy(i => i.Path).ToList());
             }
 
-            return ToOptimizedResult(GetFileSystemEntries(request).OrderBy(i => i.Path).ToList());
+            return ToOptimizedSerializedResultUsingCache(GetFileSystemEntries(request).OrderBy(i => i.Path).ToList());
         }
 
         public object Get(GetNetworkShares request)
@@ -147,7 +147,7 @@ namespace MediaBrowser.Api
 
             var shares = GetNetworkShares(path).OrderBy(i => i.Path).ToList();
 
-            return ToOptimizedResult(shares);
+            return ToOptimizedSerializedResultUsingCache(shares);
         }
 
         /// <summary>
@@ -159,7 +159,7 @@ namespace MediaBrowser.Api
         {
             var result = GetDrives().ToList();
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -189,7 +189,7 @@ namespace MediaBrowser.Api
                 .OrderBy(i => i.Path)
                 .ToList();
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

+ 3 - 3
MediaBrowser.Api/GamesService.cs

@@ -113,7 +113,7 @@ namespace MediaBrowser.Api
                 .Select(i => GetSummary(i, user))
                 .ToList();
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
@@ -134,7 +134,7 @@ namespace MediaBrowser.Api
                 })
                 .ToList();
 
-            return ToOptimizedResult(lookup);
+            return ToOptimizedSerializedResultUsingCache(lookup);
         }
 
         /// <summary>
@@ -182,7 +182,7 @@ namespace MediaBrowser.Api
                 request, item => item is Game,
                 SimilarItemsHelper.GetSimiliarityScore);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
     }
 }

+ 2 - 2
MediaBrowser.Api/Images/ImageService.cs

@@ -361,14 +361,14 @@ namespace MediaBrowser.Api.Images
 
             var result = GetItemImageInfos(item);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public object Get(GetItemByNameImageInfos request)
         {
             var result = GetItemByNameImageInfos(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

+ 3 - 3
MediaBrowser.Api/Images/RemoteImageService.cs

@@ -176,7 +176,7 @@ namespace MediaBrowser.Api.Images
 
             var result = GetImageProviders(item);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public object Get(GetItemByNameRemoteImageProviders request)
@@ -188,7 +188,7 @@ namespace MediaBrowser.Api.Images
 
             var result = GetImageProviders(item);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         private List<ImageProviderInfo> GetImageProviders(BaseItem item)
@@ -202,7 +202,7 @@ namespace MediaBrowser.Api.Images
 
             var result = GetRemoteImageResult(item, request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public object Get(GetItemByNameRemoteImages request)

+ 4 - 4
MediaBrowser.Api/InstantMixService.cs

@@ -57,7 +57,7 @@ namespace MediaBrowser.Api
 
             var result = GetInstantMixResult(request, item.Genres);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public object Get(GetInstantMixFromAlbum request)
@@ -73,7 +73,7 @@ namespace MediaBrowser.Api
 
             var result = GetInstantMixResult(request, genres);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public object Get(GetInstantMixFromMusicGenre request)
@@ -82,7 +82,7 @@ namespace MediaBrowser.Api
 
             var result = GetInstantMixResult(request, new[] { genre.Name });
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public object Get(GetInstantMixFromArtist request)
@@ -99,7 +99,7 @@ namespace MediaBrowser.Api
 
             var result = GetInstantMixResult(request, genres);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         private ItemsResult GetInstantMixResult(BaseGetSimilarItems request, IEnumerable<string> genres)

+ 1 - 1
MediaBrowser.Api/Library/FileOrganizationService.cs

@@ -95,7 +95,7 @@ namespace MediaBrowser.Api.Library
                 StartIndex = request.StartIndex
             });
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public void Delete(DeleteOriginalFile request)

+ 2 - 2
MediaBrowser.Api/Library/LibraryService.cs

@@ -77,7 +77,7 @@ namespace MediaBrowser.Api.Library
                     {
                         try
                         {
-                            return c.ResolveArgs.PhysicalLocations;
+                            return c.PhysicalLocations;
                         }
                         catch (Exception ex)
                         {
@@ -90,7 +90,7 @@ namespace MediaBrowser.Api.Library
                 })
                 .ToList();
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

+ 2 - 2
MediaBrowser.Api/Library/LibraryStructureService.cs

@@ -251,7 +251,7 @@ namespace MediaBrowser.Api.Library
             {
                 var result = _libraryManager.GetDefaultVirtualFolders().OrderBy(i => i.Name).ToList();
 
-                return ToOptimizedResult(result);
+                return ToOptimizedSerializedResultUsingCache(result);
             }
             else
             {
@@ -259,7 +259,7 @@ namespace MediaBrowser.Api.Library
 
                 var result = _libraryManager.GetVirtualFolders(user).OrderBy(i => i.Name).ToList();
 
-                return ToOptimizedResult(result);
+                return ToOptimizedSerializedResultUsingCache(result);
             }
         }
 

+ 8 - 8
MediaBrowser.Api/LibraryService.cs

@@ -284,7 +284,7 @@ namespace MediaBrowser.Api
         {
             var result = GetAncestors(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -337,7 +337,7 @@ namespace MediaBrowser.Api
                     try
                     {
                         return i.LocationType == LocationType.FileSystem &&
-                               i.ResolveArgs.PhysicalLocations.Contains(item.Path);
+                               i.PhysicalLocations.Contains(item.Path);
                     }
                     catch (Exception ex)
                     {
@@ -360,7 +360,7 @@ namespace MediaBrowser.Api
         {
             var result = GetCriticReviews(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -405,7 +405,7 @@ namespace MediaBrowser.Api
                 UniqueTypes = items.Select(i => i.GetClientTypeName()).Distinct().ToList()
             };
 
-            return ToOptimizedResult(counts);
+            return ToOptimizedSerializedResultUsingCache(counts);
         }
 
         private IEnumerable<T> FilterItems<T>(IEnumerable<T> items, GetItemCounts request, Guid userId)
@@ -552,7 +552,7 @@ namespace MediaBrowser.Api
 
             });
 
-            return ToOptimizedResult(new AllThemeMediaResult
+            return ToOptimizedSerializedResultUsingCache(new AllThemeMediaResult
             {
                 ThemeSongsResult = themeSongs,
                 ThemeVideosResult = themeVideos,
@@ -570,7 +570,7 @@ namespace MediaBrowser.Api
         {
             var result = GetThemeSongs(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         private ThemeMediaResult GetThemeSongs(GetThemeSongs request)
@@ -638,7 +638,7 @@ namespace MediaBrowser.Api
         {
             var result = GetThemeVideos(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public ThemeMediaResult GetThemeVideos(GetThemeVideos request)
@@ -748,7 +748,7 @@ namespace MediaBrowser.Api
                 })
                 .ToList();
 
-            return ToOptimizedResult(lookup);
+            return ToOptimizedSerializedResultUsingCache(lookup);
         }
 
         public ThemeMediaResult GetSoundtrackSongs(string id, Guid? userId, bool inheritFromParent)

+ 16 - 16
MediaBrowser.Api/LiveTv/LiveTvService.cs

@@ -304,7 +304,7 @@ namespace MediaBrowser.Api.LiveTv
         {
             var info = _liveTvManager.GetLiveTvInfo(CancellationToken.None).Result;
 
-            return ToOptimizedResult(info);
+            return ToOptimizedSerializedResultUsingCache(info);
         }
 
         public object Get(GetChannels request)
@@ -318,7 +318,7 @@ namespace MediaBrowser.Api.LiveTv
 
             }, CancellationToken.None).Result;
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public object Get(GetChannel request)
@@ -327,7 +327,7 @@ namespace MediaBrowser.Api.LiveTv
 
             var result = _liveTvManager.GetChannel(request.Id, CancellationToken.None, user).Result;
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public object Get(GetPrograms request)
@@ -360,7 +360,7 @@ namespace MediaBrowser.Api.LiveTv
 
             var result = _liveTvManager.GetPrograms(query, CancellationToken.None).Result;
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public object Get(GetRecommendedPrograms request)
@@ -375,7 +375,7 @@ namespace MediaBrowser.Api.LiveTv
 
             var result = _liveTvManager.GetRecommendedPrograms(query, CancellationToken.None).Result;
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public object Post(GetPrograms request)
@@ -398,7 +398,7 @@ namespace MediaBrowser.Api.LiveTv
 
             }, CancellationToken.None).Result;
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public object Get(GetRecording request)
@@ -407,14 +407,14 @@ namespace MediaBrowser.Api.LiveTv
 
             var result = _liveTvManager.GetRecording(request.Id, CancellationToken.None, user).Result;
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public object Get(GetTimer request)
         {
             var result = _liveTvManager.GetTimer(request.Id, CancellationToken.None).Result;
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public object Get(GetTimers request)
@@ -426,7 +426,7 @@ namespace MediaBrowser.Api.LiveTv
 
             }, CancellationToken.None).Result;
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public void Delete(DeleteRecording request)
@@ -465,14 +465,14 @@ namespace MediaBrowser.Api.LiveTv
 
             }, CancellationToken.None).Result;
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public object Get(GetSeriesTimer request)
         {
             var result = _liveTvManager.GetSeriesTimer(request.Id, CancellationToken.None).Result;
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public void Delete(CancelSeriesTimer request)
@@ -499,13 +499,13 @@ namespace MediaBrowser.Api.LiveTv
             {
                 var result = _liveTvManager.GetNewTimerDefaults(CancellationToken.None).Result;
 
-                return ToOptimizedResult(result);
+                return ToOptimizedSerializedResultUsingCache(result);
             }
             else
             {
                 var result = _liveTvManager.GetNewTimerDefaults(request.ProgramId, CancellationToken.None).Result;
 
-                return ToOptimizedResult(result);
+                return ToOptimizedSerializedResultUsingCache(result);
             }
         }
 
@@ -515,7 +515,7 @@ namespace MediaBrowser.Api.LiveTv
 
             var result = _liveTvManager.GetProgram(request.Id, CancellationToken.None, user).Result;
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public void Post(CreateSeriesTimer request)
@@ -544,7 +544,7 @@ namespace MediaBrowser.Api.LiveTv
 
             }, CancellationToken.None).Result;
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public object Get(GetRecordingGroup request)
@@ -556,7 +556,7 @@ namespace MediaBrowser.Api.LiveTv
 
             var group = result.Items.FirstOrDefault(i => string.Equals(i.Id, request.Id, StringComparison.OrdinalIgnoreCase));
 
-            return ToOptimizedResult(group);
+            return ToOptimizedSerializedResultUsingCache(group);
         }
 
         public object Get(GetGuideInfo request)

+ 3 - 3
MediaBrowser.Api/LocalizationService.cs

@@ -62,7 +62,7 @@ namespace MediaBrowser.Api
         {
             var result = _localization.GetParentalRatings().ToList();
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -74,7 +74,7 @@ namespace MediaBrowser.Api
         {
             var result = _localization.GetCountries().ToList();
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -86,7 +86,7 @@ namespace MediaBrowser.Api
         {
             var result = _localization.GetCultures().ToList();
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
     }
 

+ 1 - 1
MediaBrowser.Api/MoviesService.cs

@@ -76,7 +76,7 @@ namespace MediaBrowser.Api
                 request, item => item is Movie || (item is Trailer && request.IncludeTrailers),
                 SimilarItemsHelper.GetSimiliarityScore);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
     }
 }

+ 1 - 1
MediaBrowser.Api/NewsService.cs

@@ -42,7 +42,7 @@ namespace MediaBrowser.Api
 
             });
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
     }
 }

+ 2 - 2
MediaBrowser.Api/PluginService.cs

@@ -166,7 +166,7 @@ namespace MediaBrowser.Api
         {
             var result = _appHost.Plugins.OrderBy(p => p.Name).Select(p => p.GetPluginInfo()).ToList();
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -199,7 +199,7 @@ namespace MediaBrowser.Api
                 LegacyKey = _securityManager.LegacyKey
             };
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

+ 1 - 1
MediaBrowser.Api/SearchService.cs

@@ -110,7 +110,7 @@ namespace MediaBrowser.Api
         {
             var result = GetSearchHintsAsync(request).Result;
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

+ 1 - 1
MediaBrowser.Api/TrailersService.cs

@@ -69,7 +69,7 @@ namespace MediaBrowser.Api
                 request, item => item is Movie || item is Trailer,
                 SimilarItemsHelper.GetSimiliarityScore);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
     }
 }

+ 2 - 2
MediaBrowser.Api/TvShowsService.cs

@@ -183,7 +183,7 @@ namespace MediaBrowser.Api
                 request, item => item is Series,
                 SimilarItemsHelper.GetSimiliarityScore);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -210,7 +210,7 @@ namespace MediaBrowser.Api
                 Items = returnItems
             };
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         public IEnumerable<Episode> GetNextUpEpisodes(GetNextUpEpisodes request)

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

@@ -57,7 +57,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var result = GetItem(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -91,7 +91,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var result = GetResult(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

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

@@ -62,7 +62,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var result = GetItem(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -96,7 +96,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var result = GetResult(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

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

@@ -268,7 +268,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var result = GetItems(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

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

@@ -57,7 +57,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var result = GetItem(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -91,7 +91,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var result = GetResult(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

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

@@ -74,7 +74,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var result = GetItem(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -108,7 +108,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var result = GetResult(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

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

@@ -62,7 +62,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var result = GetItem(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -96,7 +96,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var result = GetResult(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

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

@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Dto;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.Entities.TV;
@@ -7,6 +8,7 @@ using MediaBrowser.Controller.Session;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Querying;
+using MediaBrowser.Model.Serialization;
 using ServiceStack;
 using System;
 using System.Collections.Generic;
@@ -411,7 +413,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var result = GetAsync(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         private List<BaseItemDto> GetAsync(GetSpecialFeatures request)
@@ -477,7 +479,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var result = GetAsync(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         private List<BaseItemDto> GetAsync(GetLocalTrailers request)
@@ -521,7 +523,7 @@ namespace MediaBrowser.Api.UserLibrary
 
             var result = _dtoService.GetBaseItemDto(item, fields, user);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -540,7 +542,7 @@ namespace MediaBrowser.Api.UserLibrary
 
             var result = _dtoService.GetBaseItemDto(item, fields, user);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -570,7 +572,7 @@ namespace MediaBrowser.Api.UserLibrary
                 TotalRecordCount = dtos.Length
             };
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

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

@@ -62,7 +62,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var result = GetItem(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -96,7 +96,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
             var result = GetResult(request);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

+ 2 - 2
MediaBrowser.Api/UserService.cs

@@ -225,7 +225,7 @@ namespace MediaBrowser.Api
                 .Select(_dtoService.GetUserDto)
                 .ToList();
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>
@@ -244,7 +244,7 @@ namespace MediaBrowser.Api
 
             var result = _dtoService.GetUserDto(user);
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
 
         /// <summary>

+ 1 - 1
MediaBrowser.Api/VideosService.cs

@@ -69,7 +69,7 @@ namespace MediaBrowser.Api
                 TotalRecordCount = items.Length
             };
 
-            return ToOptimizedResult(result);
+            return ToOptimizedSerializedResultUsingCache(result);
         }
     }
 }

+ 9 - 0
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -253,6 +253,15 @@ namespace MediaBrowser.Controller.Entities
             }
         }
 
+        [IgnoreDataMember]
+        public IEnumerable<string> PhysicalLocations
+        {
+            get
+            {
+                return ResolveArgs.PhysicalLocations;
+            }
+        }
+
         /// <summary>
         /// Resets the resolve args.
         /// </summary>

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

@@ -84,7 +84,7 @@ namespace MediaBrowser.Controller.Entities
 
             try
             {
-                locationsDicionary = ResolveArgs.PhysicalLocations.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
+                locationsDicionary = PhysicalLocations.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
             }
             catch (IOException ex)
             {
@@ -116,7 +116,7 @@ namespace MediaBrowser.Controller.Entities
 
             try
             {
-                locationsDicionary = ResolveArgs.PhysicalLocations.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
+                locationsDicionary = PhysicalLocations.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
             }
             catch (IOException ex)
             {

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

@@ -1079,7 +1079,7 @@ namespace MediaBrowser.Controller.Entities
 
                     if (i.LocationType != LocationType.Remote)
                     {
-                        if (i.ResolveArgs.PhysicalLocations.Contains(path, StringComparer.OrdinalIgnoreCase))
+                        if (i.PhysicalLocations.Contains(path, StringComparer.OrdinalIgnoreCase))
                         {
                             return true;
                         }

+ 12 - 2
MediaBrowser.Controller/Net/IHttpResultFactory.cs

@@ -50,7 +50,7 @@ namespace MediaBrowser.Controller.Net
         /// <param name="factoryFn">The factory function that creates the response object.</param>
         /// <param name="responseHeaders">The response headers.</param>
         /// <returns>System.Object.</returns>
-        object GetOptimizedResultUsingCache<T>(IRequest requestContext, Guid cacheKey, DateTime lastDateModified, TimeSpan? cacheDuration, Func<T> factoryFn, IDictionary<string, string> responseHeaders = null)
+        object GetOptimizedResultUsingCache<T>(IRequest requestContext, Guid cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration, Func<T> factoryFn, IDictionary<string, string> responseHeaders = null)
             where T : class;
 
         /// <summary>
@@ -65,7 +65,7 @@ namespace MediaBrowser.Controller.Net
         /// <param name="contentType">Type of the content.</param>
         /// <param name="responseHeaders">The response headers.</param>
         /// <returns>System.Object.</returns>
-        object GetCachedResult<T>(IRequest requestContext, Guid cacheKey, DateTime lastDateModified, TimeSpan? cacheDuration, Func<T> factoryFn, string contentType, IDictionary<string, string> responseHeaders = null)
+        object GetCachedResult<T>(IRequest requestContext, Guid cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration, Func<T> factoryFn, string contentType, IDictionary<string, string> responseHeaders = null)
             where T : class;
 
         /// <summary>
@@ -94,5 +94,15 @@ namespace MediaBrowser.Controller.Net
         /// <param name="isHeadRequest">if set to <c>true</c> [is head request].</param>
         /// <returns>System.Object.</returns>
         object GetStaticFileResult(IRequest requestContext, string path, FileShare fileShare = FileShare.Read, IDictionary<string, string> responseHeaders = null, bool isHeadRequest = false);
+
+        /// <summary>
+        /// Gets the optimized serialized result using cache.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="request">The request.</param>
+        /// <param name="result">The result.</param>
+        /// <returns>System.Object.</returns>
+        object GetOptimizedSerializedResultUsingCache<T>(IRequest request, T result)
+            where T : class;
     }
 }

+ 2 - 4
MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs

@@ -1,12 +1,10 @@
 using MediaBrowser.Common.IO;
 using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Providers.Manager;
@@ -48,9 +46,9 @@ namespace MediaBrowser.Providers.BoxSets
             return _libraryManager.UpdateItem(item, reason, cancellationToken);
         }
 
-        protected override ItemUpdateType AfterMetadataRefresh(BoxSet item)
+        protected override ItemUpdateType BeforeSave(BoxSet item)
         {
-            var updateType = base.AfterMetadataRefresh(item);
+            var updateType = base.BeforeSave(item);
 
             if (!item.LockedFields.Contains(MetadataFields.OfficialRating))
             {

+ 2 - 2
MediaBrowser.Providers/CollectionFolderImageProvider.cs

@@ -31,14 +31,14 @@ namespace MediaBrowser.Providers
 
         protected override FileSystemInfo GetImage(BaseItem item, ItemResolveArgs args, string filenameWithoutExtension)
         {
-            return item.ResolveArgs.PhysicalLocations
+            return item.PhysicalLocations
                 .Select(i => GetImageFromLocation(i, filenameWithoutExtension))
                 .FirstOrDefault(i => i != null);
         }
 
         protected override Guid GetFileSystemStamp(IEnumerable<BaseItem> items)
         {
-            var files = items.SelectMany(i => i.ResolveArgs.PhysicalLocations)
+            var files = items.SelectMany(i => i.PhysicalLocations)
                 .Select(i => new DirectoryInfo(i))
                 .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly))
                 .Where(i =>

+ 7 - 6
MediaBrowser.Providers/Manager/MetadataService.cs

@@ -100,8 +100,6 @@ namespace MediaBrowser.Providers.Manager
                     refreshResult.SetDateLastMetadataRefresh(DateTime.UtcNow);
                     refreshResult.AddImageProvidersRefreshed(result.Providers);
                 }
-
-                updateType = updateType | AfterMetadataRefresh(itemOfType);
             }
 
             // Next run remote image providers, but only if local image providers didn't throw an exception
@@ -120,6 +118,8 @@ namespace MediaBrowser.Providers.Manager
                 }
             }
 
+            updateType = updateType | BeforeSave(itemOfType);
+
             var providersHadChanges = updateType > ItemUpdateType.Unspecified;
 
             if (refreshOptions.ForceSave || providersHadChanges)
@@ -149,20 +149,21 @@ namespace MediaBrowser.Providers.Manager
         }
 
         /// <summary>
-        /// Afters the metadata refresh.
+        /// Befores the metadata refresh.
         /// </summary>
         /// <param name="item">The item.</param>
-        protected virtual ItemUpdateType AfterMetadataRefresh(TItemType item)
+        /// <returns>ItemUpdateType.</returns>
+        protected virtual ItemUpdateType BeforeMetadataRefresh(TItemType item)
         {
             return ItemUpdateType.Unspecified;
         }
 
         /// <summary>
-        /// Befores the metadata refresh.
+        /// Befores the save.
         /// </summary>
         /// <param name="item">The item.</param>
         /// <returns>ItemUpdateType.</returns>
-        protected virtual ItemUpdateType BeforeMetadataRefresh(TItemType item)
+        protected virtual ItemUpdateType BeforeSave(TItemType item)
         {
             return ItemUpdateType.Unspecified;
         }

+ 2 - 2
MediaBrowser.Providers/Music/AlbumMetadataService.cs

@@ -47,9 +47,9 @@ namespace MediaBrowser.Providers.Music
             return _libraryManager.UpdateItem(item, reason, cancellationToken);
         }
 
-        protected override ItemUpdateType AfterMetadataRefresh(MusicAlbum item)
+        protected override ItemUpdateType BeforeSave(MusicAlbum item)
         {
-            var updateType = base.AfterMetadataRefresh(item);
+            var updateType = base.BeforeSave(item);
 
             var songs = item.RecursiveChildren.OfType<Audio>().ToList(); 
             

+ 2 - 2
MediaBrowser.Providers/Music/ArtistMetadataService.cs

@@ -42,9 +42,9 @@ namespace MediaBrowser.Providers.Music
             return _libraryManager.UpdateItem(item, reason, cancellationToken);
         }
 
-        protected override ItemUpdateType AfterMetadataRefresh(MusicArtist item)
+        protected override ItemUpdateType BeforeSave(MusicArtist item)
         {
-            var updateType = base.AfterMetadataRefresh(item);
+            var updateType = base.BeforeSave(item);
 
             if (!item.IsAccessedByName && !item.LockedFields.Contains(MetadataFields.Genres))
             {

+ 2 - 2
MediaBrowser.Providers/TV/SeriesMetadataService.cs

@@ -41,9 +41,9 @@ namespace MediaBrowser.Providers.TV
             return _libraryManager.UpdateItem(item, reason, cancellationToken);
         }
 
-        protected override ItemUpdateType AfterMetadataRefresh(Series item)
+        protected override ItemUpdateType BeforeSave(Series item)
         {
-            var updateType = base.AfterMetadataRefresh(item);
+            var updateType = base.BeforeSave(item);
 
             var episodes = item.RecursiveChildren
                 .OfType<Episode>()

+ 40 - 5
MediaBrowser.Providers/TV/TvdbSeriesProvider.cs

@@ -142,24 +142,59 @@ namespace MediaBrowser.Providers.TV
             await ExtractEpisodes(seriesDataPath, Path.Combine(seriesDataPath, preferredMetadataLanguage + ".xml"), lastTvDbUpdateTime).ConfigureAwait(false);
         }
 
-        internal async Task EnsureSeriesInfo(string seriesId, string preferredMetadataLanguage, CancellationToken cancellationToken)
+        private readonly Task _cachedTask = Task.FromResult(true);
+        internal Task EnsureSeriesInfo(string seriesId, string preferredMetadataLanguage, CancellationToken cancellationToken)
         {
             var seriesDataPath = GetSeriesDataPath(_config.ApplicationPaths, seriesId);
 
             Directory.CreateDirectory(seriesDataPath);
 
-            var files = Directory.EnumerateFiles(seriesDataPath, "*.xml", SearchOption.TopDirectoryOnly)
-                .Select(Path.GetFileName)
+            var files = new DirectoryInfo(seriesDataPath).EnumerateFiles("*.xml", SearchOption.TopDirectoryOnly)
                 .ToList();
 
             var seriesXmlFilename = preferredMetadataLanguage + ".xml";
 
+            var download = false;
+            var automaticUpdatesEnabled = _config.Configuration.EnableTvDbUpdates;
+
+            var seriesFile = files.FirstOrDefault(i => string.Equals(seriesXmlFilename, i.Name, StringComparison.OrdinalIgnoreCase));
+            if (seriesFile == null || !seriesFile.Exists)
+            {
+                // No need to check age if automatic updates are enabled
+                if (!automaticUpdatesEnabled && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(seriesFile)).TotalDays > 7)
+                {
+                    download = true;
+                }
+            }
+
+            var actorsXml = files.FirstOrDefault(i => string.Equals("actors.xml", i.Name, StringComparison.OrdinalIgnoreCase));
+            if (actorsXml == null || !actorsXml.Exists)
+            {
+                // No need to check age if automatic updates are enabled
+                if (!automaticUpdatesEnabled && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(actorsXml)).TotalDays > 7)
+                {
+                    download = true;
+                }
+            }
+
+            var bannersXml = files.FirstOrDefault(i => string.Equals("banners.xml", i.Name, StringComparison.OrdinalIgnoreCase));
+            if (bannersXml == null || !bannersXml.Exists)
+            {
+                // No need to check age if automatic updates are enabled
+                if (!automaticUpdatesEnabled && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(bannersXml)).TotalDays > 7)
+                {
+                    download = true;
+                }
+            }
+
             // Only download if not already there
             // The prescan task will take care of updates so we don't need to re-download here
-            if (!files.Contains("banners.xml", StringComparer.OrdinalIgnoreCase) || !files.Contains("actors.xml", StringComparer.OrdinalIgnoreCase) || !files.Contains(seriesXmlFilename, StringComparer.OrdinalIgnoreCase))
+            if (download)
             {
-                await DownloadSeriesZip(seriesId, seriesDataPath, null, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false);
+                return DownloadSeriesZip(seriesId, seriesDataPath, null, preferredMetadataLanguage, cancellationToken);
             }
+
+            return _cachedTask;
         }
 
         /// <summary>

+ 1 - 1
MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs

@@ -279,7 +279,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
                         try
                         {
                             return i.LocationType == LocationType.FileSystem &&
-                                   i.ResolveArgs.PhysicalLocations.Contains(item.Path);
+                                   i.PhysicalLocations.Contains(item.Path);
                         }
                         catch (Exception ex)
                         {

+ 22 - 12
MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs

@@ -1,9 +1,10 @@
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
+using ServiceStack;
+using ServiceStack.Web;
 using System;
 using System.Collections.Generic;
 using System.Globalization;
@@ -11,8 +12,6 @@ using System.IO;
 using System.Net;
 using System.Text;
 using System.Threading.Tasks;
-using ServiceStack;
-using ServiceStack.Web;
 using MimeTypes = MediaBrowser.Common.Net.MimeTypes;
 
 namespace MediaBrowser.Server.Implementations.HttpServer
@@ -27,14 +26,18 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         /// </summary>
         private readonly ILogger _logger;
         private readonly IFileSystem _fileSystem;
+        private readonly IJsonSerializer _jsonSerializer;
 
         /// <summary>
-        /// Initializes a new instance of the <see cref="HttpResultFactory"/> class.
+        /// Initializes a new instance of the <see cref="HttpResultFactory" /> class.
         /// </summary>
         /// <param name="logManager">The log manager.</param>
-        public HttpResultFactory(ILogManager logManager, IFileSystem fileSystem)
+        /// <param name="fileSystem">The file system.</param>
+        /// <param name="jsonSerializer">The json serializer.</param>
+        public HttpResultFactory(ILogManager logManager, IFileSystem fileSystem, IJsonSerializer jsonSerializer)
         {
             _fileSystem = fileSystem;
+            _jsonSerializer = jsonSerializer;
             _logger = logManager.GetLogger("HttpResultFactory");
         }
 
@@ -151,12 +154,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         /// <param name="factoryFn">The factory fn.</param>
         /// <param name="responseHeaders">The response headers.</param>
         /// <returns>System.Object.</returns>
-        /// <exception cref="System.ArgumentNullException">
-        /// cacheKey
+        /// <exception cref="System.ArgumentNullException">cacheKey
         /// or
-        /// factoryFn
-        /// </exception>
-        public object GetOptimizedResultUsingCache<T>(IRequest requestContext, Guid cacheKey, DateTime lastDateModified, TimeSpan? cacheDuration, Func<T> factoryFn, IDictionary<string, string> responseHeaders = null)
+        /// factoryFn</exception>
+        public object GetOptimizedResultUsingCache<T>(IRequest requestContext, Guid cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration, Func<T> factoryFn, IDictionary<string, string> responseHeaders = null)
                where T : class
         {
             if (cacheKey == Guid.Empty)
@@ -199,7 +200,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         /// <param name="responseHeaders">The response headers.</param>
         /// <returns>System.Object.</returns>
         /// <exception cref="System.ArgumentNullException">cacheKey</exception>
-        public object GetCachedResult<T>(IRequest requestContext, Guid cacheKey, DateTime lastDateModified, TimeSpan? cacheDuration, Func<T> factoryFn, string contentType, IDictionary<string, string> responseHeaders = null)
+        public object GetCachedResult<T>(IRequest requestContext, Guid cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration, Func<T> factoryFn, string contentType, IDictionary<string, string> responseHeaders = null)
           where T : class
         {
             if (cacheKey == Guid.Empty)
@@ -661,5 +662,14 @@ namespace MediaBrowser.Server.Implementations.HttpServer
 
             throw error;
         }
+
+        public object GetOptimizedSerializedResultUsingCache<T>(IRequest request, T result)
+           where T : class
+        {
+            var json = _jsonSerializer.SerializeToString(result);
+            var cacheKey = json.GetMD5();
+
+            return GetOptimizedResultUsingCache(request, cacheKey, null, null, () => result);
+        }
     }
 }

+ 1 - 2
MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs

@@ -166,8 +166,7 @@ namespace MediaBrowser.Server.Implementations.IO
                     {
                         try
                         {
-                            // Accessing ResolveArgs could involve file system access
-                            return f.ResolveArgs.PhysicalLocations;
+                            return f.PhysicalLocations;
                         }
                         catch (IOException)
                         {

+ 5 - 2
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -270,6 +270,7 @@ namespace MediaBrowser.Server.Implementations.Library
         /// </summary>
         private string _seasonZeroDisplayName;
 
+        private bool _wizardCompleted;
         /// <summary>
         /// Records the configuration values.
         /// </summary>
@@ -278,6 +279,7 @@ namespace MediaBrowser.Server.Implementations.Library
         {
             _seasonZeroDisplayName = configuration.SeasonZeroDisplayName;
             _itemsByNamePath = ConfigurationManager.ApplicationPaths.ItemsByNamePath;
+            _wizardCompleted = configuration.IsStartupWizardCompleted;
         }
 
         /// <summary>
@@ -298,6 +300,7 @@ namespace MediaBrowser.Server.Implementations.Library
 
             var newSeasonZeroName = ConfigurationManager.Configuration.SeasonZeroDisplayName;
             var seasonZeroNameChanged = !string.Equals(_seasonZeroDisplayName, newSeasonZeroName, StringComparison.CurrentCulture);
+            var wizardChanged = config.IsStartupWizardCompleted != _wizardCompleted;
 
             RecordConfigurationValues(config);
 
@@ -308,7 +311,7 @@ namespace MediaBrowser.Server.Implementations.Library
                     await UpdateSeasonZeroNames(newSeasonZeroName, CancellationToken.None).ConfigureAwait(false);
                 }
 
-                if (seasonZeroNameChanged || ibnPathChanged)
+                if (seasonZeroNameChanged || ibnPathChanged || wizardChanged)
                 {
                     _taskManager.CancelIfRunningAndQueue<RefreshMediaLibraryTask>();
                 }
@@ -1479,7 +1482,7 @@ namespace MediaBrowser.Server.Implementations.Library
                     try
                     {
 
-                        return i.ResolveArgs.PhysicalLocations.Contains(item.Path);
+                        return i.PhysicalLocations.Contains(item.Path);
                     }
                     catch (IOException ex)
                     {

+ 1 - 1
MediaBrowser.ServerApplication/ApplicationHost.cs

@@ -250,7 +250,7 @@ namespace MediaBrowser.ServerApplication
         {
             await base.RegisterResources(progress).ConfigureAwait(false);
 
-            RegisterSingleInstance<IHttpResultFactory>(new HttpResultFactory(LogManager, FileSystemManager));
+            RegisterSingleInstance<IHttpResultFactory>(new HttpResultFactory(LogManager, FileSystemManager, JsonSerializer));
 
             RegisterSingleInstance<IServerApplicationHost>(this);
             RegisterSingleInstance<IServerApplicationPaths>(ApplicationPaths);