Pārlūkot izejas kodu

separate provider options

Luke Pulverenti 10 gadi atpakaļ
vecāks
revīzija
5f76b59e67
28 mainītis faili ar 280 papildinājumiem un 99 dzēšanām
  1. 9 0
      MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
  2. 9 0
      MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
  3. 17 0
      MediaBrowser.Model/Configuration/FanartOptions.cs
  4. 7 15
      MediaBrowser.Model/Configuration/ServerConfiguration.cs
  5. 12 0
      MediaBrowser.Model/Configuration/TheMovieDbOptions.cs
  6. 12 0
      MediaBrowser.Model/Configuration/TvdbOptions.cs
  7. 1 1
      MediaBrowser.Model/Dlna/StreamBuilder.cs
  8. 3 0
      MediaBrowser.Model/MediaBrowser.Model.csproj
  9. 10 5
      MediaBrowser.Providers/Movies/FanArtMovieUpdatesPostScanTask.cs
  10. 6 3
      MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
  11. 22 1
      MediaBrowser.Providers/Movies/MovieDbProvider.cs
  12. 1 1
      MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs
  13. 3 1
      MediaBrowser.Providers/Music/FanArtAlbumProvider.cs
  14. 6 3
      MediaBrowser.Providers/Music/FanArtArtistProvider.cs
  15. 9 5
      MediaBrowser.Providers/Music/FanArtUpdatesPostScanTask.cs
  16. 2 1
      MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
  17. 8 5
      MediaBrowser.Providers/TV/FanArtTvUpdatesPostScanTask.cs
  18. 31 8
      MediaBrowser.Providers/TV/FanartSeriesProvider.cs
  19. 1 1
      MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs
  20. 1 1
      MediaBrowser.Providers/TV/TvdbEpisodeImageProvider.cs
  21. 1 1
      MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs
  22. 1 1
      MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs
  23. 22 1
      MediaBrowser.Providers/TV/TvdbSeriesProvider.cs
  24. 8 1
      MediaBrowser.Server.Implementations/Localization/Server/server.json
  25. 2 2
      MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
  26. 5 3
      MediaBrowser.WebDashboard/Api/DashboardService.cs
  27. 68 34
      MediaBrowser.WebDashboard/Api/PackageCreator.cs
  28. 3 5
      MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj

+ 9 - 0
MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj

@@ -194,6 +194,9 @@
     <Compile Include="..\MediaBrowser.Model\Configuration\EncodingQuality.cs">
       <Link>Configuration\EncodingQuality.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Configuration\FanartOptions.cs">
+      <Link>Configuration\FanartOptions.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Configuration\ImageOption.cs">
       <Link>Configuration\ImageOption.cs</Link>
     </Compile>
@@ -227,6 +230,12 @@
     <Compile Include="..\MediaBrowser.Model\Configuration\SubtitlePlaybackMode.cs">
       <Link>Configuration\SubtitlePlaybackMode.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Configuration\TheMovieDbOptions.cs">
+      <Link>Configuration\TheMovieDbOptions.cs</Link>
+    </Compile>
+    <Compile Include="..\MediaBrowser.Model\Configuration\TvdbOptions.cs">
+      <Link>Configuration\TvdbOptions.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Configuration\UnratedItem.cs">
       <Link>Configuration\UnratedItem.cs</Link>
     </Compile>

+ 9 - 0
MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj

@@ -159,6 +159,9 @@
     <Compile Include="..\MediaBrowser.Model\Configuration\EncodingQuality.cs">
       <Link>Configuration\EncodingQuality.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Configuration\FanartOptions.cs">
+      <Link>Configuration\FanartOptions.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Configuration\ImageOption.cs">
       <Link>Configuration\ImageOption.cs</Link>
     </Compile>
@@ -192,6 +195,12 @@
     <Compile Include="..\MediaBrowser.Model\Configuration\SubtitlePlaybackMode.cs">
       <Link>Configuration\SubtitlePlaybackMode.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Configuration\TheMovieDbOptions.cs">
+      <Link>Configuration\TheMovieDbOptions.cs</Link>
+    </Compile>
+    <Compile Include="..\MediaBrowser.Model\Configuration\TvdbOptions.cs">
+      <Link>Configuration\TvdbOptions.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Configuration\UnratedItem.cs">
       <Link>Configuration\UnratedItem.cs</Link>
     </Compile>

+ 17 - 0
MediaBrowser.Model/Configuration/FanartOptions.cs

@@ -0,0 +1,17 @@
+
+namespace MediaBrowser.Model.Configuration
+{
+    public class FanartOptions
+    {
+        /// <summary>
+        /// Gets or sets a value indicating whether [enable automatic updates].
+        /// </summary>
+        /// <value><c>true</c> if [enable automatic updates]; otherwise, <c>false</c>.</value>
+        public bool EnableAutomaticUpdates { get; set; }
+        /// <summary>
+        /// Gets or sets the user API key.
+        /// </summary>
+        /// <value>The user API key.</value>
+        public string UserApiKey { get; set; }
+    }
+}

+ 7 - 15
MediaBrowser.Model/Configuration/ServerConfiguration.cs

@@ -1,5 +1,4 @@
-using System.Xml.Schema;
-using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Model.Configuration
@@ -32,10 +31,11 @@ namespace MediaBrowser.Model.Configuration
         /// </summary>
         /// <value>The HTTPS server port number.</value>
         public int HttpsPortNumber { get; set; }
-        
-        /// Gets or sets the value pointing to the file system where the ssl certiifcate is located.
+
+        /// <summary>
+        /// Gets or sets a value indicating whether [use HTTPS].
         /// </summary>
-        /// <value>The value pointing to the file system where the ssl certiifcate is located.</value>
+        /// <value><c>true</c> if [use HTTPS]; otherwise, <c>false</c>.</value>
         public bool UseHttps { get; set; }
 
         /// <summary>
@@ -154,6 +154,7 @@ namespace MediaBrowser.Model.Configuration
         /// </summary>
         /// <value><c>true</c> if [enable dashboard response caching]; otherwise, <c>false</c>.</value>
         public bool EnableDashboardResponseCaching { get; set; }
+        public bool EnableDashboardResourceMinification { get; set; }
 
         /// <summary>
         /// Allows the dashboard to be served from a custom path.
@@ -161,18 +162,8 @@ namespace MediaBrowser.Model.Configuration
         /// <value>The dashboard source path.</value>
         public string DashboardSourcePath { get; set; }
 
-        /// <summary>
-        /// Gets or sets a value indicating whether [enable tv db updates].
-        /// </summary>
-        /// <value><c>true</c> if [enable tv db updates]; otherwise, <c>false</c>.</value>
-        public bool EnableTvDbUpdates { get; set; }
-        public bool EnableTmdbUpdates { get; set; }
-
         public bool StoreArtistsInMetadata { get; set; }
 
-        public bool EnableFanArtUpdates { get; set; }
-        public string FanartApiKey { get; set; }
-
         /// <summary>
         /// Gets or sets the image saving convention.
         /// </summary>
@@ -220,6 +211,7 @@ namespace MediaBrowser.Model.Configuration
             UseHttps = false;
             CertificatePath = null;
             EnableDashboardResponseCaching = true;
+            EnableDashboardResourceMinification = true;
 
             EnableAutomaticRestart = true;
             EnableWin8HttpListener = true;

+ 12 - 0
MediaBrowser.Model/Configuration/TheMovieDbOptions.cs

@@ -0,0 +1,12 @@
+
+namespace MediaBrowser.Model.Configuration
+{
+    public class TheMovieDbOptions
+    {
+        /// <summary>
+        /// Gets or sets a value indicating whether [enable automatic updates].
+        /// </summary>
+        /// <value><c>true</c> if [enable automatic updates]; otherwise, <c>false</c>.</value>
+        public bool EnableAutomaticUpdates { get; set; }
+    }
+}

+ 12 - 0
MediaBrowser.Model/Configuration/TvdbOptions.cs

@@ -0,0 +1,12 @@
+
+namespace MediaBrowser.Model.Configuration
+{
+    public class TvdbOptions
+    {
+        /// <summary>
+        /// Gets or sets a value indicating whether [enable automatic updates].
+        /// </summary>
+        /// <value><c>true</c> if [enable automatic updates]; otherwise, <c>false</c>.</value>
+        public bool EnableAutomaticUpdates { get; set; }
+    }
+}

+ 1 - 1
MediaBrowser.Model/Dlna/StreamBuilder.cs

@@ -548,7 +548,7 @@ namespace MediaBrowser.Model.Dlna
             {
                 SubtitleProfile externalProfile = GetSubtitleProfile(options.Profile.SubtitleProfiles, SubtitleDeliveryMethod.External, _serverTextSubtitleOutputs);
 
-                if (options.Context == EncodingContext.Streaming && externalProfile != null)
+                if (externalProfile != null)
                 {
                     return externalProfile;
                 }

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

@@ -97,8 +97,11 @@
     <Compile Include="Configuration\ChapterOptions.cs" />
     <Compile Include="Configuration\CinemaModeConfiguration.cs" />
     <Compile Include="Configuration\EncodingOptions.cs" />
+    <Compile Include="Configuration\FanartOptions.cs" />
     <Compile Include="Configuration\MetadataConfiguration.cs" />
     <Compile Include="Configuration\PeopleMetadataOptions.cs" />
+    <Compile Include="Configuration\TheMovieDbOptions.cs" />
+    <Compile Include="Configuration\TvdbOptions.cs" />
     <Compile Include="Configuration\XbmcMetadataOptions.cs" />
     <Compile Include="Configuration\SubtitlePlaybackMode.cs" />
     <Compile Include="Connect\ConnectAuthenticationExchangeResult.cs" />

+ 10 - 5
MediaBrowser.Providers/Movies/FanArtMovieUpdatesPostScanTask.cs

@@ -2,6 +2,7 @@
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Providers.Music;
@@ -13,6 +14,7 @@ using System.Linq;
 using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Providers.TV;
 
 namespace MediaBrowser.Providers.Movies
 {
@@ -54,7 +56,9 @@ namespace MediaBrowser.Providers.Movies
         /// <returns>Task.</returns>
         public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
-            if (!_config.Configuration.EnableFanArtUpdates)
+            var options = FanartSeriesProvider.Current.GetFanartOptions();
+
+            if (!options.EnableAutomaticUpdates)
             {
                 progress.Report(100);
                 return;
@@ -82,7 +86,7 @@ namespace MediaBrowser.Providers.Movies
             // If this is our first time, don't do any updates and just record the timestamp
             if (!string.IsNullOrEmpty(lastUpdateTime))
             {
-                var moviesToUpdate = await GetMovieIdsToUpdate(existingDirectories, lastUpdateTime, cancellationToken).ConfigureAwait(false);
+                var moviesToUpdate = await GetMovieIdsToUpdate(existingDirectories, lastUpdateTime, options, cancellationToken).ConfigureAwait(false);
 
                 progress.Report(5);
 
@@ -96,13 +100,14 @@ namespace MediaBrowser.Providers.Movies
             progress.Report(100);
         }
 
-        private async Task<IEnumerable<string>> GetMovieIdsToUpdate(IEnumerable<string> existingIds, string lastUpdateTime, CancellationToken cancellationToken)
+        private async Task<IEnumerable<string>> GetMovieIdsToUpdate(IEnumerable<string> existingIds, string lastUpdateTime, FanartOptions options, CancellationToken cancellationToken)
         {
             var url = string.Format(UpdatesUrl, FanartArtistProvider.ApiKey, lastUpdateTime);
 
-            if (!string.IsNullOrWhiteSpace(_config.Configuration.FanartApiKey))
+            var clientKey = options.UserApiKey;
+            if (!string.IsNullOrWhiteSpace(clientKey))
             {
-                url += "&client_key=" + _config.Configuration.FanartApiKey;
+                url += "&client_key=" + clientKey;
             }
 
             // First get last time

+ 6 - 3
MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs

@@ -19,6 +19,7 @@ using System.IO;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Providers.TV;
 
 namespace MediaBrowser.Providers.Movies
 {
@@ -216,7 +217,8 @@ namespace MediaBrowser.Providers.Movies
 
         public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
         {
-            if (!_config.Configuration.EnableFanArtUpdates)
+            var options = FanartSeriesProvider.Current.GetFanartOptions();
+            if (!options.EnableAutomaticUpdates)
             {
                 return false;
             }
@@ -283,9 +285,10 @@ namespace MediaBrowser.Providers.Movies
 
             var url = string.Format(FanArtBaseUrl, FanartArtistProvider.ApiKey, id);
 
-            if (!string.IsNullOrWhiteSpace(_config.Configuration.FanartApiKey))
+            var clientKey = FanartSeriesProvider.Current.GetFanartOptions().UserApiKey;
+            if (!string.IsNullOrWhiteSpace(clientKey))
             {
-                url += "&client_key=" + _config.Configuration.FanartApiKey;
+                url += "&client_key=" + clientKey;
             }
 
             var path = GetFanartJsonPath(id);

+ 22 - 1
MediaBrowser.Providers/Movies/MovieDbProvider.cs

@@ -7,6 +7,7 @@ using MediaBrowser.Controller.Entities.Movies;
 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.Model.Providers;
@@ -371,9 +372,14 @@ namespace MediaBrowser.Providers.Movies
             return _httpClient.Get(options);
         }
 
+        public TheMovieDbOptions GetTheMovieDbOptions()
+        {
+            return _configurationManager.GetConfiguration<TheMovieDbOptions>("themoviedb");
+        }
+
         public bool HasChanged(IHasMetadata item, DateTime date)
         {
-            if (!_configurationManager.Configuration.EnableTmdbUpdates)
+            if (!GetTheMovieDbOptions().EnableAutomaticUpdates)
             {
                 return false;
             }
@@ -605,4 +611,19 @@ namespace MediaBrowser.Providers.Movies
             });
         }
     }
+
+    public class TmdbConfigStore : IConfigurationFactory
+    {
+        public IEnumerable<ConfigurationStore> GetConfigurations()
+        {
+            return new List<ConfigurationStore>
+            {
+                new ConfigurationStore
+                {
+                     Key = "themoviedb",
+                     ConfigurationType = typeof(TheMovieDbOptions)
+                }
+            };
+        }
+    }
 }

+ 1 - 1
MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs

@@ -68,7 +68,7 @@ namespace MediaBrowser.Providers.Movies
         /// <returns>Task.</returns>
         public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
-            if (!_config.Configuration.EnableTmdbUpdates)
+            if (!MovieDbProvider.Current.GetTheMovieDbOptions().EnableAutomaticUpdates)
             {
                 progress.Report(100);
                 return;

+ 3 - 1
MediaBrowser.Providers/Music/FanArtAlbumProvider.cs

@@ -16,6 +16,7 @@ using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Xml;
+using MediaBrowser.Providers.TV;
 
 namespace MediaBrowser.Providers.Music
 {
@@ -356,7 +357,8 @@ namespace MediaBrowser.Providers.Music
 
         public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
         {
-            if (!_config.Configuration.EnableFanArtUpdates)
+            var options = FanartSeriesProvider.Current.GetFanartOptions();
+            if (!options.EnableAutomaticUpdates)
             {
                 return false;
             }

+ 6 - 3
MediaBrowser.Providers/Music/FanArtArtistProvider.cs

@@ -17,6 +17,7 @@ using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Xml;
+using MediaBrowser.Providers.TV;
 
 namespace MediaBrowser.Providers.Music
 {
@@ -373,7 +374,8 @@ namespace MediaBrowser.Providers.Music
 
         public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
         {
-            if (!_config.Configuration.EnableFanArtUpdates)
+            var options = FanartSeriesProvider.Current.GetFanartOptions();
+            if (!options.EnableAutomaticUpdates)
             {
                 return false;
             }
@@ -423,9 +425,10 @@ namespace MediaBrowser.Providers.Music
 
             var url = string.Format(FanArtBaseUrl, ApiKey, musicBrainzId);
 
-            if (!string.IsNullOrWhiteSpace(_config.Configuration.FanartApiKey))
+            var clientKey = FanartSeriesProvider.Current.GetFanartOptions().UserApiKey;
+            if (!string.IsNullOrWhiteSpace(clientKey))
             {
-                url += "&client_key=" + _config.Configuration.FanartApiKey;
+                url += "&client_key=" + clientKey;
             }
 
             var xmlPath = GetArtistXmlPath(_config.ApplicationPaths, musicBrainzId);

+ 9 - 5
MediaBrowser.Providers/Music/FanArtUpdatesPostScanTask.cs

@@ -2,6 +2,7 @@
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Serialization;
 using System;
@@ -12,6 +13,7 @@ using System.Linq;
 using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Providers.TV;
 
 namespace MediaBrowser.Providers.Music
 {
@@ -53,7 +55,9 @@ namespace MediaBrowser.Providers.Music
         /// <returns>Task.</returns>
         public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
-            if (!_config.Configuration.EnableFanArtUpdates)
+            var options = FanartSeriesProvider.Current.GetFanartOptions();
+
+            if (!options.EnableAutomaticUpdates)
             {
                 progress.Report(100);
                 return;
@@ -81,7 +85,7 @@ namespace MediaBrowser.Providers.Music
             // If this is our first time, don't do any updates and just record the timestamp
             if (!string.IsNullOrEmpty(lastUpdateTime))
             {
-                var artistsToUpdate = await GetArtistIdsToUpdate(existingDirectories, lastUpdateTime, cancellationToken).ConfigureAwait(false);
+                var artistsToUpdate = await GetArtistIdsToUpdate(existingDirectories, lastUpdateTime, options, cancellationToken).ConfigureAwait(false);
 
                 progress.Report(5);
 
@@ -102,13 +106,13 @@ namespace MediaBrowser.Providers.Music
         /// <param name="lastUpdateTime">The last update time.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task{IEnumerable{System.String}}.</returns>
-        private async Task<IEnumerable<string>> GetArtistIdsToUpdate(IEnumerable<string> existingArtistIds, string lastUpdateTime, CancellationToken cancellationToken)
+        private async Task<IEnumerable<string>> GetArtistIdsToUpdate(IEnumerable<string> existingArtistIds, string lastUpdateTime, FanartOptions options, CancellationToken cancellationToken)
         {
             var url = string.Format(UpdatesUrl, FanartArtistProvider.ApiKey, lastUpdateTime);
 
-            if (!string.IsNullOrWhiteSpace(_config.Configuration.FanartApiKey))
+            if (!string.IsNullOrWhiteSpace(options.UserApiKey))
             {
-                url += "&client_key=" + _config.Configuration.FanartApiKey;
+                url += "&client_key=" + options.UserApiKey;
             }
             
             // First get last time

+ 2 - 1
MediaBrowser.Providers/TV/FanArtSeasonProvider.cs

@@ -223,7 +223,8 @@ namespace MediaBrowser.Providers.TV
 
         public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
         {
-            if (!_config.Configuration.EnableFanArtUpdates)
+            var options = FanartSeriesProvider.Current.GetFanartOptions();
+            if (!options.EnableAutomaticUpdates)
             {
                 return false;
             }

+ 8 - 5
MediaBrowser.Providers/TV/FanArtTvUpdatesPostScanTask.cs

@@ -2,6 +2,7 @@
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Providers.Music;
@@ -54,7 +55,9 @@ namespace MediaBrowser.Providers.TV
         /// <returns>Task.</returns>
         public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
-            if (!_config.Configuration.EnableFanArtUpdates)
+            var options = FanartSeriesProvider.Current.GetFanartOptions();
+
+            if (!options.EnableAutomaticUpdates)
             {
                 progress.Report(100);
                 return;
@@ -82,7 +85,7 @@ namespace MediaBrowser.Providers.TV
             // If this is our first time, don't do any updates and just record the timestamp
             if (!string.IsNullOrEmpty(lastUpdateTime))
             {
-                var seriesToUpdate = await GetSeriesIdsToUpdate(existingDirectories, lastUpdateTime, cancellationToken).ConfigureAwait(false);
+                var seriesToUpdate = await GetSeriesIdsToUpdate(existingDirectories, lastUpdateTime, options, cancellationToken).ConfigureAwait(false);
 
                 progress.Report(5);
 
@@ -103,13 +106,13 @@ namespace MediaBrowser.Providers.TV
         /// <param name="lastUpdateTime">The last update time.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task{IEnumerable{System.String}}.</returns>
-        private async Task<IEnumerable<string>> GetSeriesIdsToUpdate(IEnumerable<string> existingSeriesIds, string lastUpdateTime, CancellationToken cancellationToken)
+        private async Task<IEnumerable<string>> GetSeriesIdsToUpdate(IEnumerable<string> existingSeriesIds, string lastUpdateTime, FanartOptions options, CancellationToken cancellationToken)
         {
             var url = string.Format(UpdatesUrl, FanartArtistProvider.ApiKey, lastUpdateTime);
 
-            if (!string.IsNullOrWhiteSpace(_config.Configuration.FanartApiKey))
+            if (!string.IsNullOrWhiteSpace(options.UserApiKey))
             {
-                url += "&client_key=" + _config.Configuration.FanartApiKey;
+                url += "&client_key=" + options.UserApiKey;
             }
 
             // First get last time

+ 31 - 8
MediaBrowser.Providers/TV/FanartSeriesProvider.cs

@@ -6,6 +6,7 @@ using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Net;
@@ -161,10 +162,10 @@ namespace MediaBrowser.Providers.TV
             PopulateImages(list, obj.tvposter, ImageType.Primary, 1000, 1426);
         }
 
-        private void PopulateImages(List<RemoteImageInfo> list, 
-            List<Image> images, 
-            ImageType type, 
-            int width, 
+        private void PopulateImages(List<RemoteImageInfo> list,
+            List<Image> images,
+            ImageType type,
+            int width,
             int height,
             bool allowSeasonAll = false)
         {
@@ -283,6 +284,11 @@ namespace MediaBrowser.Providers.TV
             }
         }
 
+        public FanartOptions GetFanartOptions()
+        {
+            return _config.GetConfiguration<FanartOptions>("fanart");
+        }
+
         /// <summary>
         /// Downloads the series json.
         /// </summary>
@@ -295,11 +301,12 @@ namespace MediaBrowser.Providers.TV
 
             var url = string.Format(FanArtBaseUrl, FanartArtistProvider.ApiKey, tvdbId);
 
-            if (!string.IsNullOrWhiteSpace(_config.Configuration.FanartApiKey))
+            var clientKey = GetFanartOptions().UserApiKey;
+            if (!string.IsNullOrWhiteSpace(clientKey))
             {
-                url += "&client_key=" + _config.Configuration.FanartApiKey;
+                url += "&client_key=" + clientKey;
             }
-            
+
             var path = GetFanartJsonPath(tvdbId);
 
             Directory.CreateDirectory(Path.GetDirectoryName(path));
@@ -336,7 +343,8 @@ namespace MediaBrowser.Providers.TV
 
         public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
         {
-            if (!_config.Configuration.EnableFanArtUpdates)
+            var options = GetFanartOptions();
+            if (!options.EnableAutomaticUpdates)
             {
                 return false;
             }
@@ -383,4 +391,19 @@ namespace MediaBrowser.Providers.TV
             public List<Image> seasonbanner { get; set; }
         }
     }
+
+    public class FanartConfigStore : IConfigurationFactory
+    {
+        public IEnumerable<ConfigurationStore> GetConfigurations()
+        {
+            return new List<ConfigurationStore>
+            {
+                new ConfigurationStore
+                {
+                     Key = "fanart",
+                     ConfigurationType = typeof(FanartOptions)
+                }
+            };
+        }
+    }
 }

+ 1 - 1
MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs

@@ -369,7 +369,7 @@ namespace MediaBrowser.Providers.TV
 
         public bool HasChanged(IHasMetadata item, DateTime date)
         {
-            if (!_configurationManager.Configuration.EnableTmdbUpdates)
+            if (!MovieDbProvider.Current.GetTheMovieDbOptions().EnableAutomaticUpdates)
             {
                 return false;
             }

+ 1 - 1
MediaBrowser.Providers/TV/TvdbEpisodeImageProvider.cs

@@ -193,7 +193,7 @@ namespace MediaBrowser.Providers.TV
             if (!episode.IsVirtualUnaired)
             {
                 // For non-unaired items, only enable if configured
-                if (!_config.Configuration.EnableTvDbUpdates)
+                if (!TvdbSeriesProvider.Current.GetTvDbOptions().EnableAutomaticUpdates)
                 {
                     return false;
                 }

+ 1 - 1
MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs

@@ -362,7 +362,7 @@ namespace MediaBrowser.Providers.TV
             if (item.LocationType != LocationType.Virtual)
             {
                 // For non-virtual items, only enable if configured
-                if (!_config.Configuration.EnableTvDbUpdates)
+                if (!TvdbSeriesProvider.Current.GetTvDbOptions().EnableAutomaticUpdates)
                 {
                     return false;
                 }

+ 1 - 1
MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs

@@ -340,7 +340,7 @@ namespace MediaBrowser.Providers.TV
 
         public bool HasChanged(IHasMetadata item, MetadataStatus status, IDirectoryService directoryService)
         {
-            if (!_config.Configuration.EnableTvDbUpdates)
+            if (!TvdbSeriesProvider.Current.GetTvDbOptions().EnableAutomaticUpdates)
             {
                 return false;
             }

+ 22 - 1
MediaBrowser.Providers/TV/TvdbSeriesProvider.cs

@@ -6,6 +6,7 @@ using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Logging;
@@ -224,6 +225,11 @@ namespace MediaBrowser.Providers.TV
             await ExtractEpisodes(seriesDataPath, Path.Combine(seriesDataPath, preferredMetadataLanguage + ".xml"), lastTvDbUpdateTime).ConfigureAwait(false);
         }
 
+        public TvdbOptions GetTvDbOptions()
+        {
+            return _config.GetConfiguration<TvdbOptions>("tvdb");
+        }
+
         private readonly Task _cachedTask = Task.FromResult(true);
         internal Task EnsureSeriesInfo(string seriesId, string preferredMetadataLanguage, CancellationToken cancellationToken)
         {
@@ -237,7 +243,7 @@ namespace MediaBrowser.Providers.TV
             var seriesXmlFilename = preferredMetadataLanguage + ".xml";
 
             var download = false;
-            var automaticUpdatesEnabled = _config.Configuration.EnableTvDbUpdates;
+            var automaticUpdatesEnabled = GetTvDbOptions().EnableAutomaticUpdates;
 
             const int cacheDays = 2;
 
@@ -1219,4 +1225,19 @@ namespace MediaBrowser.Providers.TV
             });
         }
     }
+
+    public class TvdbConfigStore : IConfigurationFactory
+    {
+        public IEnumerable<ConfigurationStore> GetConfigurations()
+        {
+            return new List<ConfigurationStore>
+            {
+                new ConfigurationStore
+                {
+                     Key = "tvdb",
+                     ConfigurationType = typeof(TvdbOptions)
+                }
+            };
+        }
+    }
 }

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

@@ -40,6 +40,12 @@
     "OptionIAcceptTermsOfService": "I accept the terms of service",
     "ButtonPrivacyPolicy": "Privacy policy",
     "ButtonTermsOfService": "Terms of Service",
+    "HeaderDeveloperOptions": "Developer Options",
+    "OptionEnableWebClientResponseCache": "Enable web client response caching",
+    "OptionDisableForDevelopmentHelp": "Disable these for web client development purposes",
+    "OptionEnableWebClientResourceMinification": "Enable web client resource minification",
+    "LabelDashboardSourcePath": "Web client source path:",
+    "LabelDashboardSourcePathHelp": "If running the server from source, specify the path to the dashboard-ui folder. All web client files will be served from this location.",
     "ButtonOk": "Ok",
     "ButtonCancel": "Cancel",
     "ButtonNew": "New",
@@ -47,6 +53,7 @@
     "HeaderAudio": "Audio",
     "HeaderVideo": "Video",
     "HeaderPaths": "Paths",
+    "ButtonDonateWithPayPal": "Donate with PayPal",
     "OptionDetectArchiveFilesAsMedia": "Detect archive files as media",
     "OptionDetectArchiveFilesAsMediaHelp": "If enabled, files with .rar and .zip extensions will be detected as media files.",
     "LabelEnterConnectUserName": "User name or email:",
@@ -1308,7 +1315,7 @@
     "MessageNoTrailersFound": "No trailers found. Install the Trailer channel to enhance your movie experience by adding a library of internet trailers.",
     "HeaderNewUsers": "New Users",
     "ButtonSignUp": "Sign up",
-    "ButtonForgotPassword": "Forgot password?",
+    "ButtonForgotPassword": "Forgot password",
     "OptionDisableUserPreferences": "Disable access to user preferences",
     "OptionDisableUserPreferencesHelp": "If enabled, only administrators will be able to configure user profile images, passwords, and language preferences.",
     "HeaderSelectServer": "Select Server",

+ 2 - 2
MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs

@@ -702,8 +702,8 @@ namespace MediaBrowser.Server.Implementations.Sync
             var mediaSources = hasMediaSources.GetMediaSources(false).ToList();
 
             var preferredAudio = string.IsNullOrEmpty(user.Configuration.AudioLanguagePreference)
-            ? new string[] { }
-            : new[] { user.Configuration.AudioLanguagePreference };
+                ? new string[] { }
+                : new[] { user.Configuration.AudioLanguagePreference };
 
             var preferredSubs = string.IsNullOrEmpty(user.Configuration.SubtitleLanguagePreference)
                 ? new List<string> { }

+ 5 - 3
MediaBrowser.WebDashboard/Api/DashboardService.cs

@@ -134,7 +134,7 @@ namespace MediaBrowser.WebDashboard.Api
         {
             var page = ServerEntryPoint.Instance.PluginConfigurationPages.First(p => p.Name.Equals(request.Name, StringComparison.OrdinalIgnoreCase));
 
-            return ResultFactory.GetStaticResult(Request, page.Plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.html"), () => GetPackageCreator().ModifyHtml(page.GetHtmlStream(), null));
+            return ResultFactory.GetStaticResult(Request, page.Plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.html"), () => GetPackageCreator().ModifyHtml(page.GetHtmlStream(), null, false));
         }
 
         /// <summary>
@@ -249,8 +249,10 @@ namespace MediaBrowser.WebDashboard.Api
         /// <returns>Task{Stream}.</returns>
         private Task<Stream> GetResourceStream(string path, string localizationCulture)
         {
+            var minify = _serverConfigurationManager.Configuration.EnableDashboardResourceMinification;
+
             return GetPackageCreator()
-                .GetResource(path, localizationCulture, _appHost.ApplicationVersion.ToString());
+                .GetResource(path, localizationCulture, _appHost.ApplicationVersion.ToString(), minify);
         }
 
         private PackageCreator GetPackageCreator()
@@ -321,7 +323,7 @@ namespace MediaBrowser.WebDashboard.Api
 
         private async Task DumpFile(string resourceVirtualPath, string destinationFilePath, string culture, string appVersion)
         {
-            using (var stream = await GetPackageCreator().GetResource(resourceVirtualPath, culture, appVersion).ConfigureAwait(false))
+            using (var stream = await GetPackageCreator().GetResource(resourceVirtualPath, culture, appVersion, true).ConfigureAwait(false))
             {
                 using (var fs = _fileSystem.GetFileStream(destinationFilePath, FileMode.Create, FileAccess.Write, FileShare.Read))
                 {

+ 68 - 34
MediaBrowser.WebDashboard/Api/PackageCreator.cs

@@ -10,6 +10,7 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using WebMarkupMin.Core.Minifiers;
+using WebMarkupMin.Core.Settings;
 
 namespace MediaBrowser.WebDashboard.Api
 {
@@ -30,9 +31,9 @@ namespace MediaBrowser.WebDashboard.Api
             _jsonSerializer = jsonSerializer;
         }
 
-        public async Task<Stream> GetResource(string path, 
+        public async Task<Stream> GetResource(string path,
             string localizationCulture,
-            string appVersion)
+            string appVersion, bool enableMinification)
         {
             var isHtml = IsHtml(path);
 
@@ -40,11 +41,11 @@ namespace MediaBrowser.WebDashboard.Api
 
             if (path.Equals("scripts/all.js", StringComparison.OrdinalIgnoreCase))
             {
-                resourceStream = await GetAllJavascript(localizationCulture, appVersion).ConfigureAwait(false);
+                resourceStream = await GetAllJavascript(localizationCulture, appVersion, enableMinification).ConfigureAwait(false);
             }
             else if (path.Equals("css/all.css", StringComparison.OrdinalIgnoreCase))
             {
-                resourceStream = await GetAllCss().ConfigureAwait(false);
+                resourceStream = await GetAllCss(enableMinification).ConfigureAwait(false);
             }
             else
             {
@@ -57,7 +58,7 @@ namespace MediaBrowser.WebDashboard.Api
                 // jQuery ajax doesn't seem to handle if-modified-since correctly
                 if (isHtml)
                 {
-                    resourceStream = await ModifyHtml(resourceStream, localizationCulture).ConfigureAwait(false);
+                    resourceStream = await ModifyHtml(resourceStream, localizationCulture, enableMinification).ConfigureAwait(false);
                 }
             }
 
@@ -106,8 +107,9 @@ namespace MediaBrowser.WebDashboard.Api
         /// </summary>
         /// <param name="sourceStream">The source stream.</param>
         /// <param name="localizationCulture">The localization culture.</param>
+        /// <param name="enableMinification">if set to <c>true</c> [enable minification].</param>
         /// <returns>Task{Stream}.</returns>
-        public async Task<Stream> ModifyHtml(Stream sourceStream, string localizationCulture)
+        public async Task<Stream> ModifyHtml(Stream sourceStream, string localizationCulture, bool enableMinification)
         {
             using (sourceStream)
             {
@@ -128,16 +130,27 @@ namespace MediaBrowser.WebDashboard.Api
                         html = html.Replace("<html>", "<html lang=\"" + lang + "\">");
                     }
 
-                    //try
-                    //{
-                    //    var minifier = new HtmlMinifier(new HtmlMinificationSettings(true));
+                    if (enableMinification)
+                    {
+                        try
+                        {
+                            var minifier = new HtmlMinifier(new HtmlMinificationSettings());
+                            var result = minifier.Minify(html, false);
 
-                    //    html = minifier.Minify(html).MinifiedContent;
-                    //}
-                    //catch (Exception ex)
-                    //{
-                    //    Logger.ErrorException("Error minifying html", ex);
-                    //}
+                            if (result.Errors.Count > 0)
+                            {
+                                _logger.Error("Error minifying html: " + result.Errors[0].Message);
+                            }
+                            else
+                            {
+                                html = result.MinifiedContent;
+                            }
+                        }
+                        catch (Exception ex)
+                        {
+                            _logger.ErrorException("Error minifying html", ex);
+                        }
+                    }
                 }
 
                 var version = GetType().Assembly.GetName().Version;
@@ -221,7 +234,6 @@ namespace MediaBrowser.WebDashboard.Api
             var files = new[]
                             {
                                 "scripts/all.js" + versionString,
-                                "thirdparty/jstree3.0.8/jstree.min.js",
                                 "thirdparty/swipebox-master/js/jquery.swipebox.min.js" + versionString
             };
 
@@ -236,7 +248,7 @@ namespace MediaBrowser.WebDashboard.Api
         /// Gets a stream containing all concatenated javascript
         /// </summary>
         /// <returns>Task{Stream}.</returns>
-        private async Task<Stream> GetAllJavascript(string culture, string version)
+        private async Task<Stream> GetAllJavascript(string culture, string version, bool enableMinification)
         {
             var memoryStream = new MemoryStream();
             var newLineBytes = Encoding.UTF8.GetBytes(Environment.NewLine);
@@ -250,6 +262,8 @@ namespace MediaBrowser.WebDashboard.Api
             await AppendResource(memoryStream, "thirdparty/cast_sender.js", newLineBytes).ConfigureAwait(false);
             await AppendResource(memoryStream, "thirdparty/browser.js", newLineBytes).ConfigureAwait(false);
 
+            await AppendResource(memoryStream, "thirdparty/jstree3.0.8/jstree.js", newLineBytes).ConfigureAwait(false);
+
             await AppendLocalization(memoryStream, culture).ConfigureAwait(false);
             await memoryStream.WriteAsync(newLineBytes, 0, newLineBytes.Length).ConfigureAwait(false);
 
@@ -304,15 +318,25 @@ namespace MediaBrowser.WebDashboard.Api
 
             var js = builder.ToString();
 
-            try
+            if (enableMinification)
             {
-                var result = new CrockfordJsMinifier().Minify(js, false, Encoding.UTF8);
+                try
+                {
+                    var result = new CrockfordJsMinifier().Minify(js, false, Encoding.UTF8);
 
-                js = result.MinifiedContent;
-            }
-            catch (Exception ex)
-            {
-                _logger.ErrorException("Error minifying javascript", ex);
+                    if (result.Errors.Count > 0)
+                    {
+                        _logger.Error("Error minifying javascript: " + result.Errors[0].Message);
+                    }
+                    else
+                    {
+                        js = result.MinifiedContent;
+                    }
+                }
+                catch (Exception ex)
+                {
+                    _logger.ErrorException("Error minifying javascript", ex);
+                }
             }
 
             var bytes = Encoding.UTF8.GetBytes(js);
@@ -518,7 +542,7 @@ namespace MediaBrowser.WebDashboard.Api
         /// Gets all CSS.
         /// </summary>
         /// <returns>Task{Stream}.</returns>
-        private async Task<Stream> GetAllCss()
+        private async Task<Stream> GetAllCss(bool enableMinification)
         {
             var files = new[]
                                   {
@@ -561,16 +585,26 @@ namespace MediaBrowser.WebDashboard.Api
 
             var css = builder.ToString();
 
-            //try
-            //{
-            //    var result = new KristensenCssMinifier().Minify(builder.ToString(), false, Encoding.UTF8);
+            if (enableMinification)
+            {
+                try
+                {
+                    var result = new KristensenCssMinifier().Minify(builder.ToString(), false, Encoding.UTF8);
 
-            //    css = result.MinifiedContent;
-            //}
-            //catch (Exception ex)
-            //{
-            //    Logger.ErrorException("Error minifying css", ex);
-            //}
+                    if (result.Errors.Count > 0)
+                    {
+                        _logger.Error("Error minifying css: " + result.Errors[0].Message);
+                    }
+                    else
+                    {
+                        css = result.MinifiedContent;
+                    }
+                }
+                catch (Exception ex)
+                {
+                    _logger.ErrorException("Error minifying css", ex);
+                }
+            }
 
             var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(css));
 

+ 3 - 5
MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj

@@ -90,6 +90,9 @@
     <Content Include="dashboard-ui\css\images\server.png">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
+    <Content Include="dashboard-ui\css\images\splash.png">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
     <Content Include="dashboard-ui\css\images\tour\dashboard\help.png">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
@@ -2152,11 +2155,6 @@
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
   </ItemGroup>
-  <ItemGroup>
-    <Content Include="dashboard-ui\css\images\supporter\donatepaypal.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-  </ItemGroup>
   <ItemGroup>
     <Content Include="dashboard-ui\css\images\supporter\registerpaypal.png">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>