Bladeren bron

added toggles for metadata settings

Luke Pulverenti 11 jaren geleden
bovenliggende
commit
17bf59dfe3
29 gewijzigde bestanden met toevoegingen van 203 en 98 verwijderingen
  1. 8 1
      MediaBrowser.Api/Images/RemoteImageService.cs
  2. 19 2
      MediaBrowser.Api/Library/LibraryStructureService.cs
  3. 1 1
      MediaBrowser.Controller/Entities/Folder.cs
  4. 8 0
      MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs
  5. 8 0
      MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs
  6. 1 1
      MediaBrowser.Controller/Providers/IProviderManager.cs
  7. 13 2
      MediaBrowser.Model/Configuration/MetadataOptions.cs
  8. 11 1
      MediaBrowser.Model/Providers/ImageProviderInfo.cs
  9. 1 1
      MediaBrowser.Providers/AdultVideos/AdultVideoXmlProvider.cs
  10. 3 7
      MediaBrowser.Providers/BaseXmlProvider.cs
  11. 2 2
      MediaBrowser.Providers/BoxSets/BoxSetXmlProvider.cs
  12. 1 1
      MediaBrowser.Providers/Folders/FolderXmlProvider.cs
  13. 2 2
      MediaBrowser.Providers/Games/GameSystemXmlProvider.cs
  14. 1 1
      MediaBrowser.Providers/Games/GameXmlProvider.cs
  15. 2 2
      MediaBrowser.Providers/LiveTv/ChannelXmlProvider.cs
  16. 2 20
      MediaBrowser.Providers/Manager/ItemImageProvider.cs
  17. 10 2
      MediaBrowser.Providers/Manager/MetadataService.cs
  18. 90 28
      MediaBrowser.Providers/Manager/ProviderManager.cs
  19. 1 1
      MediaBrowser.Providers/Movies/MovieXmlProvider.cs
  20. 1 1
      MediaBrowser.Providers/Movies/TrailerXmlProvider.cs
  21. 2 2
      MediaBrowser.Providers/Music/AlbumXmlProvider.cs
  22. 2 2
      MediaBrowser.Providers/Music/ArtistXmlProvider.cs
  23. 1 1
      MediaBrowser.Providers/Music/MusicVideoXmlProvider.cs
  24. 2 2
      MediaBrowser.Providers/People/PersonXmlProvider.cs
  25. 0 9
      MediaBrowser.Providers/TV/EpisodeXmlProvider.cs
  26. 2 2
      MediaBrowser.Providers/TV/SeasonXmlProvider.cs
  27. 2 2
      MediaBrowser.Providers/TV/SeriesXmlProvider.cs
  28. 6 1
      MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
  29. 1 1
      MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs

+ 8 - 1
MediaBrowser.Api/Images/RemoteImageService.cs

@@ -221,10 +221,17 @@ namespace MediaBrowser.Api.Images
 
             var imagesList = images.ToList();
 
+            var allProviders = _providerManager.GetRemoteImageProviderInfo(item);
+
+            if (request.Type.HasValue)
+            {
+                allProviders = allProviders.Where(i => i.SupportedImages.Contains(request.Type.Value));
+            }
+
             var result = new RemoteImageResult
             {
                 TotalRecordCount = imagesList.Count,
-                Providers = imagesList.Select(i => i.ProviderName)
+                Providers = allProviders.Select(i => i.Name)
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .ToList()
             };

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

@@ -167,15 +167,32 @@ namespace MediaBrowser.Api.Library
         public bool RefreshLibrary { get; set; }
     }
 
-    [Route("/Library/Changes/Path", "POST")]
+    [Route("/Library/Changes/New", "POST")]
     public class ReportChangedPath : IReturnVoid
     {
         /// <summary>
         /// Gets or sets the name.
         /// </summary>
         /// <value>The name.</value>
-        [ApiMember(Name = "Path", Description = "The path that was changed.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
+        [ApiMember(Name = "Path", Description = "The path that was changed.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
         public string Path { get; set; }
+
+        [ApiMember(Name = "ImageUrl", Description = "Optional thumbnail image url of the content.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
+        public string ImageUrl { get; set; }
+    }
+
+    [Route("/Library/Episodes/New", "POST")]
+    public class ReportNewEpisode : IReturnVoid
+    {
+        /// <summary>
+        /// Gets or sets the name.
+        /// </summary>
+        /// <value>The name.</value>
+        [ApiMember(Name = "TvdbId", Description = "The tvdb id of the new episode.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
+        public string TvdbId { get; set; }
+
+        [ApiMember(Name = "ImageUrl", Description = "Optional thumbnail image url of the content.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
+        public string ImageUrl { get; set; }
     }
     
     /// <summary>

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

@@ -521,7 +521,7 @@ namespace MediaBrowser.Controller.Entities
 
             foreach (var child in children)
             {
-                if (tasks.Count >= 2)
+                if (tasks.Count >= 8)
                 {
                     await Task.WhenAll(tasks).ConfigureAwait(false);
                     tasks.Clear();

+ 8 - 0
MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs

@@ -67,5 +67,13 @@ namespace MediaBrowser.Controller.LiveTv
         {
             return false;
         }
+
+        public override bool SupportsLocalMetadata
+        {
+            get
+            {
+                return false;
+            }
+        }
     }
 }

+ 8 - 0
MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs

@@ -67,5 +67,13 @@ namespace MediaBrowser.Controller.LiveTv
         {
             return false;
         }
+
+        public override bool SupportsLocalMetadata
+        {
+            get
+            {
+                return false;
+            }
+        }
     }
 }

+ 1 - 1
MediaBrowser.Controller/Providers/IProviderManager.cs

@@ -94,6 +94,6 @@ namespace MediaBrowser.Controller.Providers
         /// </summary>
         /// <param name="item">The item.</param>
         /// <returns>MetadataOptions.</returns>
-        MetadataOptions GetMetadataOptions(IHasMetadata item);
+        MetadataOptions GetMetadataOptions(IHasImages item);
     }
 }

+ 13 - 2
MediaBrowser.Model/Configuration/MetadataOptions.cs

@@ -15,8 +15,14 @@ namespace MediaBrowser.Model.Configuration
         public ImageOption[] ImageOptions { get; set; }
 
         public string[] DisabledMetadataSavers { get; set; }
-        public string[] LocalMetadataReaders { get; set; }
+        public string[] LocalMetadataReaderOrder { get; set; }
 
+        public string[] DisabledMetadataFetchers { get; set; }
+        public string[] MetadataFetcherOrder { get; set; }
+
+        public string[] DisabledImageFetchers { get; set; }
+        public string[] ImageFetcherOrder { get; set; }
+        
         public MetadataOptions()
             : this(3, 1280)
         {
@@ -36,7 +42,12 @@ namespace MediaBrowser.Model.Configuration
 
             ImageOptions = imageOptions.ToArray();
             DisabledMetadataSavers = new string[] { };
-            LocalMetadataReaders = new string[] { };
+            LocalMetadataReaderOrder = new string[] { };
+
+            DisabledMetadataFetchers = new string[] { };
+            MetadataFetcherOrder = new string[] { };
+            DisabledImageFetchers = new string[] { };
+            ImageFetcherOrder = new string[] { };
         }
 
         public int GetLimit(ImageType type)

+ 11 - 1
MediaBrowser.Model/Providers/ImageProviderInfo.cs

@@ -1,4 +1,7 @@
-namespace MediaBrowser.Model.Providers
+using System.Collections.Generic;
+using MediaBrowser.Model.Entities;
+
+namespace MediaBrowser.Model.Providers
 {
     /// <summary>
     /// Class ImageProviderInfo.
@@ -10,5 +13,12 @@
         /// </summary>
         /// <value>The name.</value>
         public string Name { get; set; }
+
+        public List<ImageType> SupportedImages { get; set; }
+
+        public ImageProviderInfo()
+        {
+            SupportedImages = new List<ImageType>();
+        }
     }
 }

+ 1 - 1
MediaBrowser.Providers/AdultVideos/AdultVideoXmlProvider.cs

@@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.AdultVideos
             new MovieXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
         }
 
-        protected override FileInfo GetXmlFile(ItemInfo info)
+        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
         {
             return MovieXmlProvider.GetXmlFileInfo(info, FileSystem);
         }

+ 3 - 7
MediaBrowser.Providers/BaseXmlProvider.cs

@@ -1,6 +1,7 @@
 using MediaBrowser.Common.IO;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Logging;
 using System;
 using System.IO;
 using System.Threading;
@@ -17,7 +18,7 @@ namespace MediaBrowser.Providers
         {
             var result = new LocalMetadataResult<T>();
 
-            var file = GetXmlFile(info);
+            var file = GetXmlFile(info, new DirectoryService(new NullLogger()));
 
             if (file == null)
             {
@@ -58,12 +59,7 @@ namespace MediaBrowser.Providers
             FileSystem = fileSystem;
         }
 
-        protected abstract FileInfo GetXmlFile(ItemInfo info);
-
-        protected virtual FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
-        {
-            return GetXmlFile(info);
-        }
+        protected abstract FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService);
 
         public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
         {

+ 2 - 2
MediaBrowser.Providers/BoxSets/BoxSetXmlProvider.cs

@@ -25,9 +25,9 @@ namespace MediaBrowser.Providers.BoxSets
             new BaseItemXmlParser<BoxSet>(_logger).Fetch(result.Item, path, cancellationToken);
         }
 
-        protected override FileInfo GetXmlFile(ItemInfo info)
+        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
         {
-            return new FileInfo(Path.Combine(info.Path, "collection.xml"));
+            return directoryService.GetFile(Path.Combine(info.Path, "collection.xml"));
         }
     }
 }

+ 1 - 1
MediaBrowser.Providers/Folders/FolderXmlProvider.cs

@@ -25,7 +25,7 @@ namespace MediaBrowser.Providers.Folders
             new BaseItemXmlParser<Folder>(_logger).Fetch(result.Item, path, cancellationToken);
         }
 
-        protected override FileInfo GetXmlFile(ItemInfo info)
+        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
         {
             return new FileInfo(Path.Combine(info.Path, "folder.xml"));
         }

+ 2 - 2
MediaBrowser.Providers/Games/GameSystemXmlProvider.cs

@@ -22,9 +22,9 @@ namespace MediaBrowser.Providers.Games
             new GameSystemXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
         }
 
-        protected override FileInfo GetXmlFile(ItemInfo info)
+        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
         {
-            return new FileInfo(Path.Combine(info.Path, "gamesystem.xml"));
+            return directoryService.GetFile(Path.Combine(info.Path, "gamesystem.xml"));
         }
     }
 }

+ 1 - 1
MediaBrowser.Providers/Games/GameXmlProvider.cs

@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Games
             new GameXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
         }
 
-        protected override FileInfo GetXmlFile(ItemInfo info)
+        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
         {
             var fileInfo = FileSystem.GetFileSystemInfo(info.Path);
 

+ 2 - 2
MediaBrowser.Providers/LiveTv/ChannelXmlProvider.cs

@@ -22,9 +22,9 @@ namespace MediaBrowser.Providers.LiveTv
             new BaseItemXmlParser<LiveTvChannel>(_logger).Fetch(result.Item, path, cancellationToken);
         }
 
-        protected override FileInfo GetXmlFile(ItemInfo info)
+        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
         {
-            return new FileInfo(Path.Combine(info.Path, "channel.xml"));
+            return directoryService.GetFile(Path.Combine(info.Path, "channel.xml"));
         }
     }
 }

+ 2 - 20
MediaBrowser.Providers/Manager/ItemImageProvider.cs

@@ -55,7 +55,7 @@ namespace MediaBrowser.Providers.Manager
         {
             var result = new RefreshResult { UpdateType = ItemUpdateType.None };
 
-            var providers = GetImageProviders(item, imageProviders).ToList();
+            var providers = imageProviders.ToList();
 
             var providerIds = new List<Guid>();
 
@@ -213,7 +213,7 @@ namespace MediaBrowser.Providers.Manager
 
                 _logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name);
 
-                var images = await provider.GetAllImages(item, cancellationToken).ConfigureAwait(false);
+                var images = await _providerManager.GetAvailableRemoteImages(item, cancellationToken, provider.Name).ConfigureAwait(false);
                 var list = images.ToList();
 
                 foreach (var type in _singularImages)
@@ -244,24 +244,6 @@ namespace MediaBrowser.Providers.Manager
             }
         }
 
-        /// <summary>
-        /// Gets the image providers.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <param name="imageProviders">The image providers.</param>
-        /// <returns>IEnumerable{IImageProvider}.</returns>
-        private IEnumerable<IImageProvider> GetImageProviders(IHasImages item, IEnumerable<IImageProvider> imageProviders)
-        {
-            var providers = imageProviders;
-
-            if (!_config.Configuration.EnableInternetProviders)
-            {
-                providers = providers.Where(i => !(i is IRemoteImageProvider));
-            }
-
-            return providers;
-        }
-
         public bool MergeImages(IHasImages item, List<LocalImageInfo> images)
         {
             var changed = false;

+ 10 - 2
MediaBrowser.Providers/Manager/MetadataService.cs

@@ -159,7 +159,15 @@ namespace MediaBrowser.Providers.Manager
         /// <returns>ItemUpdateType.</returns>
         protected virtual ItemUpdateType BeforeSave(TItemType item)
         {
-            return ItemUpdateType.None;
+            var updateType = ItemUpdateType.None;
+
+            if (string.IsNullOrEmpty(item.Name) && !string.IsNullOrEmpty(item.Path))
+            {
+                item.Name = Path.GetFileNameWithoutExtension(item.Path);
+                updateType = updateType | ItemUpdateType.MetadataEdit;
+            }
+
+            return updateType;
         }
 
         /// <summary>
@@ -318,7 +326,7 @@ namespace MediaBrowser.Providers.Manager
             }
 
             // Local metadata is king - if any is found don't run remote providers
-            if (!options.ReplaceAllMetadata && !hasLocalMetadata)
+            if ((!options.ReplaceAllMetadata && !hasLocalMetadata) || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh)
             {
                 await ExecuteRemoteProviders(item, temp, providers.OfType<IRemoteMetadataProvider<TItemType, TIdType>>(), refreshResult, cancellationToken).ConfigureAwait(false);
             }

+ 90 - 28
MediaBrowser.Providers/Manager/ProviderManager.cs

@@ -211,7 +211,7 @@ namespace MediaBrowser.Providers.Manager
         /// <returns>Task{IEnumerable{RemoteImageInfo}}.</returns>
         public async Task<IEnumerable<RemoteImageInfo>> GetAvailableRemoteImages(IHasImages item, CancellationToken cancellationToken, string providerName = null, ImageType? type = null)
         {
-            var providers = GetRemoteImageProviders(item);
+            var providers = GetRemoteImageProviders(item, true);
 
             if (!string.IsNullOrEmpty(providerName))
             {
@@ -277,27 +277,38 @@ namespace MediaBrowser.Providers.Manager
         /// <returns>IEnumerable{IImageProvider}.</returns>
         public IEnumerable<ImageProviderInfo> GetRemoteImageProviderInfo(IHasImages item)
         {
-            return GetRemoteImageProviders(item).Select(i => new ImageProviderInfo
+            return GetRemoteImageProviders(item, true).Select(i => new ImageProviderInfo
             {
-                Name = i.Name
+                Name = i.Name,
+                SupportedImages = i.GetSupportedImages(item).ToList()
             });
         }
 
         public IEnumerable<IImageProvider> GetImageProviders(IHasImages item)
         {
-            return ImageProviders.Where(i =>
+            return GetImageProviders(item, GetMetadataOptions(item), false);
+        }
+
+        private IEnumerable<IImageProvider> GetImageProviders(IHasImages item, MetadataOptions options, bool includeDisabled)
+        {
+            return ImageProviders.Where(i => CanRefresh(i, item, options, includeDisabled))
+            .OrderBy(i =>
             {
-                try
+                // See if there's a user-defined order
+                if (!(i is ILocalImageProvider))
                 {
-                    return i.Supports(item);
-                }
-                catch (Exception ex)
-                {
-                    _logger.ErrorException("{0} failed in Supports for type {1}", ex, i.GetType().Name, item.GetType().Name);
-                    return false;
+                    var index = Array.IndexOf(options.ImageFetcherOrder, i.Name);
+
+                    if (index != -1)
+                    {
+                        return index;
+                    }
                 }
 
-            }).OrderBy(GetOrder);
+                // Not configured. Just return some high number to put it at the end.
+                return 100;
+            })
+            .ThenBy(GetOrder);
         }
 
         public IEnumerable<IMetadataProvider<T>> GetMetadataProviders<T>(IHasMetadata item)
@@ -312,13 +323,13 @@ namespace MediaBrowser.Providers.Manager
             where T : IHasMetadata
         {
             return _metadataProviders.OfType<IMetadataProvider<T>>()
-                .Where(i => CanRefresh(i, item, includeDisabled))
+                .Where(i => CanRefresh(i, item, options, includeDisabled))
                 .OrderBy(i =>
                 {
                     // See if there's a user-defined order
                     if (i is ILocalMetadataProvider)
                     {
-                        var index = Array.IndexOf(options.LocalMetadataReaders, i.Name);
+                        var index = Array.IndexOf(options.LocalMetadataReaderOrder, i.Name);
 
                         if (index != -1)
                         {
@@ -326,29 +337,46 @@ namespace MediaBrowser.Providers.Manager
                         }
                     }
 
+                    // See if there's a user-defined order
+                    if (i is IRemoteMetadataProvider)
+                    {
+                        var index = Array.IndexOf(options.MetadataFetcherOrder, i.Name);
+
+                        if (index != -1)
+                        {
+                            return index;
+                        }
+                    }
+                    
                     // Not configured. Just return some high number to put it at the end.
                     return 100;
                 })
                 .ThenBy(GetOrder);
         }
 
-        private IEnumerable<IRemoteImageProvider> GetRemoteImageProviders(IHasImages item)
+        private IEnumerable<IRemoteImageProvider> GetRemoteImageProviders(IHasImages item, bool includeDisabled)
         {
-            return GetImageProviders(item).OfType<IRemoteImageProvider>();
+            var options = GetMetadataOptions(item);
+
+            return GetImageProviders(item, options, includeDisabled).OfType<IRemoteImageProvider>();
         }
 
-        /// <summary>
-        /// Determines whether this instance can refresh the specified provider.
-        /// </summary>
-        /// <param name="provider">The provider.</param>
-        /// <param name="item">The item.</param>
-        /// <param name="includeDisabled">if set to <c>true</c> [include disabled].</param>
-        /// <returns><c>true</c> if this instance can refresh the specified provider; otherwise, <c>false</c>.</returns>
-        private bool CanRefresh(IMetadataProvider provider, IHasMetadata item, bool includeDisabled)
+        private bool CanRefresh(IMetadataProvider provider, IHasMetadata item, MetadataOptions options, bool includeDisabled)
         {
-            if (!includeDisabled && !ConfigurationManager.Configuration.EnableInternetProviders && provider is IRemoteMetadataProvider)
+            if (!includeDisabled)
             {
-                return false;
+                if (provider is IRemoteMetadataProvider)
+                {
+                    if (!ConfigurationManager.Configuration.EnableInternetProviders)
+                    {
+                        return false;
+                    }
+
+                    if (Array.IndexOf(options.DisabledMetadataFetchers, provider.Name) != -1)
+                    {
+                        return false;
+                    }
+                }
             }
 
             if (!item.SupportsLocalMetadata && provider is ILocalMetadataProvider)
@@ -368,6 +396,40 @@ namespace MediaBrowser.Providers.Manager
             return true;
         }
 
+        private bool CanRefresh(IImageProvider provider, IHasImages item, MetadataOptions options, bool includeDisabled)
+        {
+            if (!includeDisabled)
+            {
+                if (provider is IRemoteImageProvider)
+                {
+                    if (!ConfigurationManager.Configuration.EnableInternetProviders)
+                    {
+                        return false;
+                    }
+
+                    if (Array.IndexOf(options.DisabledImageFetchers, provider.Name) != -1)
+                    {
+                        return false;
+                    }
+                }
+            }
+
+            if (!item.SupportsLocalMetadata && provider is ILocalImageProvider)
+            {
+                return false;
+            }
+
+            try
+            {
+                return provider.Supports(item);
+            }
+            catch (Exception ex)
+            {
+                _logger.ErrorException("{0} failed in Supports for type {1}", ex, provider.GetType().Name, item.GetType().Name);
+                return false;
+            }
+        }
+
         /// <summary>
         /// Gets the order.
         /// </summary>
@@ -454,7 +516,7 @@ namespace MediaBrowser.Providers.Manager
                 ItemType = typeof(T).Name
             };
 
-            var imageProviders = GetImageProviders(dummy).ToList();
+            var imageProviders = GetImageProviders(dummy, options, true).ToList();
 
             AddMetadataPlugins(summary.Plugins, dummy, options);
             AddImagePlugins(summary.Plugins, dummy, imageProviders);
@@ -513,7 +575,7 @@ namespace MediaBrowser.Providers.Manager
             }));
         }
 
-        public MetadataOptions GetMetadataOptions(IHasMetadata item)
+        public MetadataOptions GetMetadataOptions(IHasImages item)
         {
             var type = item.GetType().Name;
 

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

@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Movies
             new MovieXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
         }
 
-        protected override FileInfo GetXmlFile(ItemInfo info)
+        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
         {
             return GetXmlFileInfo(info, FileSystem);
         }

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

@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Movies
             new MovieXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
         }
 
-        protected override FileInfo GetXmlFile(ItemInfo info)
+        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
         {
             return MovieXmlProvider.GetXmlFileInfo(info, FileSystem);
         }

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

@@ -22,9 +22,9 @@ namespace MediaBrowser.Providers.Music
             new BaseItemXmlParser<MusicAlbum>(_logger).Fetch(result.Item, path, cancellationToken);
         }
 
-        protected override FileInfo GetXmlFile(ItemInfo info)
+        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
         {
-            return new FileInfo(Path.Combine(info.Path, "album.xml"));
+            return directoryService.GetFile(Path.Combine(info.Path, "album.xml"));
         }
     }
 }

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

@@ -22,9 +22,9 @@ namespace MediaBrowser.Providers.Music
             new BaseItemXmlParser<MusicArtist>(_logger).Fetch(result.Item, path, cancellationToken);
         }
 
-        protected override FileInfo GetXmlFile(ItemInfo info)
+        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
         {
-            return new FileInfo(Path.Combine(info.Path, "artist.xml"));
+            return directoryService.GetFile(Path.Combine(info.Path, "artist.xml"));
         }
     }
 }

+ 1 - 1
MediaBrowser.Providers/Music/MusicVideoXmlProvider.cs

@@ -24,7 +24,7 @@ namespace MediaBrowser.Providers.Music
             new MusicVideoXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
         }
 
-        protected override FileInfo GetXmlFile(ItemInfo info)
+        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
         {
             return MovieXmlProvider.GetXmlFileInfo(info, FileSystem);
         }

+ 2 - 2
MediaBrowser.Providers/People/PersonXmlProvider.cs

@@ -22,9 +22,9 @@ namespace MediaBrowser.Providers.People
             new BaseItemXmlParser<Person>(_logger).Fetch(result.Item, path, cancellationToken);
         }
 
-        protected override FileInfo GetXmlFile(ItemInfo info)
+        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
         {
-            return new FileInfo(Path.Combine(info.Path, "person.xml"));
+            return directoryService.GetFile(Path.Combine(info.Path, "person.xml"));
         }
     }
 }

+ 0 - 9
MediaBrowser.Providers/TV/EpisodeXmlProvider.cs

@@ -22,15 +22,6 @@ namespace MediaBrowser.Providers.TV
             new EpisodeXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
         }
 
-        protected override FileInfo GetXmlFile(ItemInfo info)
-        {
-            var metadataPath = Path.GetDirectoryName(info.Path);
-            metadataPath = Path.Combine(metadataPath, "metadata");
-            var metadataFile = Path.Combine(metadataPath, Path.ChangeExtension(Path.GetFileName(info.Path), ".xml"));
-
-            return new FileInfo(metadataFile);
-        }
-
         protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
         {
             var metadataPath = Path.GetDirectoryName(info.Path);

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

@@ -25,9 +25,9 @@ namespace MediaBrowser.Providers.TV
             new BaseItemXmlParser<Season>(_logger).Fetch(result.Item, path, cancellationToken);
         }
 
-        protected override FileInfo GetXmlFile(ItemInfo info)
+        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
         {
-            return new FileInfo(Path.Combine(info.Path, "season.xml"));
+            return directoryService.GetFile(Path.Combine(info.Path, "season.xml"));
         }
     }
 }

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

@@ -25,9 +25,9 @@ namespace MediaBrowser.Providers.TV
             new SeriesXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
         }
 
-        protected override FileInfo GetXmlFile(ItemInfo info)
+        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
         {
-            return new FileInfo(Path.Combine(info.Path, "series.xml"));
+            return directoryService.GetFile(Path.Combine(info.Path, "series.xml"));
         }
     }
 }

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

@@ -793,10 +793,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 double percent = numComplete;
                 percent /= allChannelsList.Count;
 
-                progress.Report(90 * percent + 10);
+                progress.Report(80 * percent + 10);
             }
 
             _programs = programs.ToDictionary(i => i.Id);
+
+            // Load these now which will prefetch metadata
+            await GetRecordings(new RecordingQuery(), cancellationToken).ConfigureAwait(false);
+            
+            progress.Report(100);
         }
 
         private double GetGuideDays(int channelCount)

+ 1 - 1
MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs

@@ -210,7 +210,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
                 }
                 catch (Exception ex)
                 {
-                    _logger.ErrorException("{0} failed processing WebSocket message {1}", ex, i.GetType().Name, result.MessageType);
+                    _logger.ErrorException("{0} failed processing WebSocket message {1}", ex, i.GetType().Name, result.MessageType ?? string.Empty);
                 }
             }));