Преглед на файлове

use conditional caching on some json responses

Luke Pulverenti преди 11 години
родител
ревизия
351cfef7a7
променени са 48 файла, в които са добавени 216 реда и са изтрити 138 реда
  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);