Browse Source

fixed xml providers running over and over

Luke Pulverenti 11 năm trước cách đây
mục cha
commit
3d40c5ba36
42 tập tin đã thay đổi với 314 bổ sung386 xóa
  1. 1 9
      MediaBrowser.Api/ApiEntryPoint.cs
  2. 4 13
      MediaBrowser.Api/Playback/BaseStreamingService.cs
  3. 10 40
      MediaBrowser.Common.Implementations/BaseApplicationPaths.cs
  4. 16 10
      MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
  5. 3 6
      MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
  6. 1 4
      MediaBrowser.Common/Plugins/BasePlugin.cs
  7. 2 8
      MediaBrowser.Controller/Entities/User.cs
  8. 1 4
      MediaBrowser.Controller/IO/FileSystem.cs
  9. 1 4
      MediaBrowser.Controller/MediaInfo/FFMpegManager.cs
  10. 16 5
      MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
  11. 12 10
      MediaBrowser.Providers/FolderProviderFromXml.cs
  12. 21 16
      MediaBrowser.Providers/Games/GameProviderFromXml.cs
  13. 12 10
      MediaBrowser.Providers/Games/GameSystemProviderFromXml.cs
  14. 1 4
      MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
  15. 1 4
      MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
  16. 12 10
      MediaBrowser.Providers/Movies/BoxSetProviderFromXml.cs
  17. 13 16
      MediaBrowser.Providers/Movies/FanArtMovieProvider.cs
  18. 3 4
      MediaBrowser.Providers/Movies/FanArtMovieUpdatesPrescanTask.cs
  19. 9 2
      MediaBrowser.Providers/Movies/MovieDbProvider.cs
  20. 24 33
      MediaBrowser.Providers/Movies/MovieProviderFromXml.cs
  21. 12 10
      MediaBrowser.Providers/Movies/PersonProviderFromXml.cs
  22. 12 10
      MediaBrowser.Providers/Music/ArtistProviderFromXml.cs
  23. 13 16
      MediaBrowser.Providers/Music/FanArtArtistProvider.cs
  24. 3 4
      MediaBrowser.Providers/Music/FanArtUpdatesPrescanTask.cs
  25. 12 2
      MediaBrowser.Providers/Savers/GameXmlSaver.cs
  26. 15 3
      MediaBrowser.Providers/Savers/MovieXmlSaver.cs
  27. 1 4
      MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
  28. 2 2
      MediaBrowser.Providers/TV/EpisodeImageFromMediaLocationProvider.cs
  29. 7 6
      MediaBrowser.Providers/TV/EpisodeProviderFromXml.cs
  30. 13 16
      MediaBrowser.Providers/TV/FanArtTVProvider.cs
  31. 3 4
      MediaBrowser.Providers/TV/FanArtTvUpdatesPrescanTask.cs
  32. 13 16
      MediaBrowser.Providers/TV/RemoteSeriesProvider.cs
  33. 12 10
      MediaBrowser.Providers/TV/SeasonProviderFromXml.cs
  34. 13 11
      MediaBrowser.Providers/TV/SeriesProviderFromXml.cs
  35. 3 4
      MediaBrowser.Providers/TV/TvdbPrescanTask.cs
  36. 4 16
      MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs
  37. 5 8
      MediaBrowser.Server.Implementations/Library/LibraryManager.cs
  38. 1 4
      MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs
  39. 1 4
      MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
  40. 1 4
      MediaBrowser.Server.Implementations/Providers/ImageSaver.cs
  41. 1 4
      MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs
  42. 4 16
      MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs

+ 1 - 9
MediaBrowser.Api/ApiEntryPoint.cs

@@ -258,15 +258,7 @@ namespace MediaBrowser.Api
             {
                 hasExited = process.HasExited;
             }
-            catch (Win32Exception ex)
-            {
-                Logger.ErrorException("Error determining if ffmpeg process has exited for {0}", ex, job.Path);
-            }
-            catch (InvalidOperationException ex)
-            {
-                Logger.ErrorException("Error determining if ffmpeg process has exited for {0}", ex, job.Path);
-            }
-            catch (NotSupportedException ex)
+            catch (Exception ex)
             {
                 Logger.ErrorException("Error determining if ffmpeg process has exited for {0}", ex, job.Path);
             }

+ 4 - 13
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -358,10 +358,7 @@ namespace MediaBrowser.Api.Playback
                 {
                     var parentPath = Path.GetDirectoryName(path);
 
-                    if (!Directory.Exists(parentPath))
-                    {
-                        Directory.CreateDirectory(parentPath);
-                    }
+                    Directory.CreateDirectory(parentPath);
 
                     var task = MediaEncoder.ExtractTextSubtitle(inputPath, type, subtitleStream.Index, offset, path, CancellationToken.None);
 
@@ -396,10 +393,7 @@ namespace MediaBrowser.Api.Playback
                 {
                     var parentPath = Path.GetDirectoryName(path);
 
-                    if (!Directory.Exists(parentPath))
-                    {
-                        Directory.CreateDirectory(parentPath);
-                    }
+                    Directory.CreateDirectory(parentPath);
 
                     var task = MediaEncoder.ConvertTextSubtitleToAss(subtitleStream.Path, path, subtitleStream.Language, offset, CancellationToken.None);
 
@@ -599,10 +593,7 @@ namespace MediaBrowser.Api.Playback
         {
             var parentPath = Path.GetDirectoryName(outputPath);
 
-            if (!Directory.Exists(parentPath))
-            {
-                Directory.CreateDirectory(parentPath);
-            }
+            Directory.CreateDirectory(parentPath);
 
             var video = state.Item as Video;
 
@@ -648,7 +639,7 @@ namespace MediaBrowser.Api.Playback
             {
                 process.Start();
             }
-            catch (Win32Exception ex)
+            catch (Exception ex)
             {
                 Logger.ErrorException("Error starting ffmpeg", ex);
 

+ 10 - 40
MediaBrowser.Common.Implementations/BaseApplicationPaths.cs

@@ -72,10 +72,7 @@ namespace MediaBrowser.Common.Implementations
                 {
                     _dataDirectory = Path.Combine(ProgramDataPath, "data");
 
-                    if (!Directory.Exists(_dataDirectory))
-                    {
-                        Directory.CreateDirectory(_dataDirectory);
-                    }
+                    Directory.CreateDirectory(_dataDirectory);
                 }
 
                 return _dataDirectory;
@@ -98,10 +95,7 @@ namespace MediaBrowser.Common.Implementations
                 {
                     _imageCachePath = Path.Combine(CachePath, "images");
 
-                    if (!Directory.Exists(_imageCachePath))
-                    {
-                        Directory.CreateDirectory(_imageCachePath);
-                    }
+                    Directory.CreateDirectory(_imageCachePath);
                 }
 
                 return _imageCachePath;
@@ -123,10 +117,7 @@ namespace MediaBrowser.Common.Implementations
                 if (_pluginsPath == null)
                 {
                     _pluginsPath = Path.Combine(ProgramDataPath, "plugins");
-                    if (!Directory.Exists(_pluginsPath))
-                    {
-                        Directory.CreateDirectory(_pluginsPath);
-                    }
+                    Directory.CreateDirectory(_pluginsPath);
                 }
 
                 return _pluginsPath;
@@ -148,10 +139,7 @@ namespace MediaBrowser.Common.Implementations
                 if (_pluginConfigurationsPath == null)
                 {
                     _pluginConfigurationsPath = Path.Combine(PluginsPath, "configurations");
-                    if (!Directory.Exists(_pluginConfigurationsPath))
-                    {
-                        Directory.CreateDirectory(_pluginConfigurationsPath);
-                    }
+                    Directory.CreateDirectory(_pluginConfigurationsPath);
                 }
 
                 return _pluginConfigurationsPath;
@@ -170,10 +158,7 @@ namespace MediaBrowser.Common.Implementations
                 if (_tempUpdatePath == null)
                 {
                     _tempUpdatePath = Path.Combine(ProgramDataPath, "updates");
-                    if (!Directory.Exists(_tempUpdatePath))
-                    {
-                        Directory.CreateDirectory(_tempUpdatePath);
-                    }
+                    Directory.CreateDirectory(_tempUpdatePath);
                 }
 
                 return _tempUpdatePath;
@@ -195,10 +180,7 @@ namespace MediaBrowser.Common.Implementations
                 if (_logDirectoryPath == null)
                 {
                     _logDirectoryPath = Path.Combine(ProgramDataPath, "logs");
-                    if (!Directory.Exists(_logDirectoryPath))
-                    {
-                        Directory.CreateDirectory(_logDirectoryPath);
-                    }
+                    Directory.CreateDirectory(_logDirectoryPath);
                 }
                 return _logDirectoryPath;
             }
@@ -219,10 +201,7 @@ namespace MediaBrowser.Common.Implementations
                 if (_configurationDirectoryPath == null)
                 {
                     _configurationDirectoryPath = Path.Combine(ProgramDataPath, "config");
-                    if (!Directory.Exists(_configurationDirectoryPath))
-                    {
-                        Directory.CreateDirectory(_configurationDirectoryPath);
-                    }
+                    Directory.CreateDirectory(_configurationDirectoryPath);
                 }
                 return _configurationDirectoryPath;
             }
@@ -256,10 +235,7 @@ namespace MediaBrowser.Common.Implementations
                 {
                     _cachePath = Path.Combine(ProgramDataPath, "cache");
 
-                    if (!Directory.Exists(_cachePath))
-                    {
-                        Directory.CreateDirectory(_cachePath);
-                    }
+                    Directory.CreateDirectory(_cachePath);
                 }
 
                 return _cachePath;
@@ -282,10 +258,7 @@ namespace MediaBrowser.Common.Implementations
                 {
                     _tempDirectory = Path.Combine(CachePath, "temp");
 
-                    if (!Directory.Exists(_tempDirectory))
-                    {
-                        Directory.CreateDirectory(_tempDirectory);
-                    }
+                    Directory.CreateDirectory(_tempDirectory);
                 }
 
                 return _tempDirectory;
@@ -318,10 +291,7 @@ namespace MediaBrowser.Common.Implementations
                 programDataPath = Path.GetFullPath(programDataPath);
             }
 
-            if (!Directory.Exists(programDataPath))
-            {
-                Directory.CreateDirectory(programDataPath);
-            }
+            Directory.CreateDirectory(programDataPath);
 
             return programDataPath;
         }

+ 16 - 10
MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs

@@ -220,10 +220,10 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
                     {
                         options.ResourcePool.Release();
                     }
-                    
+
                     throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true };
                 }
-                
+
                 _logger.Info("HttpClientManager.Get url: {0}", options.Url);
 
                 try
@@ -512,10 +512,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
             if (operationCanceledException != null)
             {
                 // Cleanup
-                if (File.Exists(tempFile))
-                {
-                    File.Delete(tempFile);
-                }
+                DeleteTempFile(tempFile);
 
                 return GetCancellationException(options.Url, options.CancellationToken, operationCanceledException);
             }
@@ -525,10 +522,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
             var httpRequestException = ex as HttpRequestException;
 
             // Cleanup
-            if (File.Exists(tempFile))
-            {
-                File.Delete(tempFile);
-            }
+            DeleteTempFile(tempFile);
 
             if (httpRequestException != null)
             {
@@ -538,6 +532,18 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
             return ex;
         }
 
+        private void DeleteTempFile(string file)
+        {
+            try
+            {
+                File.Delete(file);
+            }
+            catch (IOException)
+            {
+                // Might not have been created at all. No need to worry.
+            }
+        }
+
         /// <summary>
         /// Validates the params.
         /// </summary>

+ 3 - 6
MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs

@@ -431,7 +431,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
         {
             var path = Path.Combine(ApplicationPaths.ConfigurationDirectoryPath, "ScheduledTasks");
 
-            if (create && !Directory.Exists(path))
+            if (create)
             {
                 Directory.CreateDirectory(path);
             }
@@ -448,7 +448,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
         {
             var path = Path.Combine(ApplicationPaths.DataPath, "ScheduledTasks");
 
-            if (create && !Directory.Exists(path))
+            if (create)
             {
                 Directory.CreateDirectory(path);
             }
@@ -507,10 +507,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
 
             var parentPath = Path.GetDirectoryName(path);
 
-            if (!Directory.Exists(parentPath))
-            {
-                Directory.CreateDirectory(parentPath);
-            }
+            Directory.CreateDirectory(parentPath);
 
             JsonSerializer.SerializeToFile(triggers.Select(ScheduledTaskHelpers.GetTriggerInfo), path);
         }

+ 1 - 4
MediaBrowser.Common/Plugins/BasePlugin.cs

@@ -234,10 +234,7 @@ namespace MediaBrowser.Common.Plugins
                     // We can always make this configurable if/when needed
                     _dataFolderPath = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(ConfigurationFileName));
 
-                    if (!Directory.Exists(_dataFolderPath))
-                    {
-                        Directory.CreateDirectory(_dataFolderPath);
-                    }
+                    Directory.CreateDirectory(_dataFolderPath);
                 }
 
                 return _dataFolderPath;

+ 2 - 8
MediaBrowser.Controller/Entities/User.cs

@@ -30,10 +30,7 @@ namespace MediaBrowser.Controller.Entities
             {
                 var path = Configuration.UseCustomLibrary ? GetRootFolderPath(Name) : ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
 
-                if (!Directory.Exists(path))
-                {
-                    Directory.CreateDirectory(path);
-                }
+                Directory.CreateDirectory(path);
 
                 return path;
             }
@@ -256,10 +253,7 @@ namespace MediaBrowser.Controller.Entities
                 {
                     _configurationDirectoryPath = GetConfigurationDirectoryPath(Name);
 
-                    if (!Directory.Exists(_configurationDirectoryPath))
-                    {
-                        Directory.CreateDirectory(_configurationDirectoryPath);
-                    }
+                    Directory.CreateDirectory(_configurationDirectoryPath);
                 }
 
                 return _configurationDirectoryPath;

+ 1 - 4
MediaBrowser.Controller/IO/FileSystem.cs

@@ -205,10 +205,7 @@ namespace MediaBrowser.Controller.IO
             }
 
             // Check if the target directory exists, if not, create it. 
-            if (!Directory.Exists(target))
-            {
-                Directory.CreateDirectory(target);
-            }
+            Directory.CreateDirectory(target);
 
             foreach (var file in Directory.EnumerateFiles(source))
             {

+ 1 - 4
MediaBrowser.Controller/MediaInfo/FFMpegManager.cs

@@ -159,10 +159,7 @@ namespace MediaBrowser.Controller.MediaInfo
                         {
                             var parentPath = Path.GetDirectoryName(path);
 
-                            if (!Directory.Exists(parentPath))
-                            {
-                                Directory.CreateDirectory(parentPath);
-                            }
+                            Directory.CreateDirectory(parentPath);
                             
                             await _encoder.ExtractImage(inputPath, type, video.Video3DFormat, time, path, cancellationToken).ConfigureAwait(false);
                             chapter.ImagePath = path;

+ 16 - 5
MediaBrowser.Controller/Providers/BaseMetadataProvider.cs

@@ -233,27 +233,27 @@ namespace MediaBrowser.Controller.Providers
                 throw new ArgumentNullException("providerInfo");
             }
 
-            if (CompareDate(item) > providerInfo.LastRefreshed)
+            if (RefreshOnVersionChange && !String.Equals(ProviderVersion, providerInfo.ProviderVersion))
             {
                 return true;
             }
 
-            if (RefreshOnFileSystemStampChange && item.LocationType == LocationType.FileSystem && HasFileSystemStampChanged(item, providerInfo))
+            if (RequiresInternet && DateTime.UtcNow > (providerInfo.LastRefreshed.AddDays(ConfigurationManager.Configuration.MetadataRefreshDays)))
             {
                 return true;
             }
 
-            if (RefreshOnVersionChange && !String.Equals(ProviderVersion, providerInfo.ProviderVersion))
+            if (providerInfo.LastRefreshStatus != ProviderRefreshStatus.Success)
             {
                 return true;
             }
 
-            if (RequiresInternet && DateTime.UtcNow > (providerInfo.LastRefreshed.AddDays(ConfigurationManager.Configuration.MetadataRefreshDays)))
+            if (NeedsRefreshBasedOnCompareDate(item, providerInfo))
             {
                 return true;
             }
 
-            if (providerInfo.LastRefreshStatus != ProviderRefreshStatus.Success)
+            if (RefreshOnFileSystemStampChange && item.LocationType == LocationType.FileSystem && HasFileSystemStampChanged(item, providerInfo))
             {
                 return true;
             }
@@ -261,6 +261,17 @@ namespace MediaBrowser.Controller.Providers
             return false;
         }
 
+        /// <summary>
+        /// Needses the refresh based on compare date.
+        /// </summary>
+        /// <param name="item">The item.</param>
+        /// <param name="providerInfo">The provider info.</param>
+        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
+        protected virtual bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
+        {
+            return CompareDate(item) > providerInfo.LastRefreshed;
+        }
+
         /// <summary>
         /// Determines if the item's file system stamp has changed from the last time the provider refreshed
         /// </summary>

+ 12 - 10
MediaBrowser.Providers/FolderProviderFromXml.cs

@@ -1,5 +1,6 @@
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
@@ -42,16 +43,17 @@ namespace MediaBrowser.Providers
             get { return MetadataProviderPriority.First; }
         }
 
-        /// <summary>
-        /// Override this to return the date that should be compared to the last refresh date
-        /// to determine if this provider should be re-fetched.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns>DateTime.</returns>
-        protected override DateTime CompareDate(BaseItem item)
+        private const string XmlFileName = "folder.xml";
+        protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
         {
-            var entry = item.MetaLocation != null ? item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "folder.xml")) : null;
-            return entry != null ? entry.LastWriteTimeUtc : DateTime.MinValue;
+            var xml = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
+
+            if (xml == null)
+            {
+                return false;
+            }
+
+            return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
         }
 
         /// <summary>
@@ -76,7 +78,7 @@ namespace MediaBrowser.Providers
         {
             cancellationToken.ThrowIfCancellationRequested();
 
-            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "folder.xml"));
+            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
 
             if (metadataFile != null)
             {

+ 21 - 16
MediaBrowser.Providers/Games/GameProviderFromXml.cs

@@ -7,6 +7,7 @@ using System;
 using System.IO;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Providers.Savers;
 
 namespace MediaBrowser.Providers.Games
 {
@@ -33,10 +34,18 @@ namespace MediaBrowser.Providers.Games
             return item is Game;
         }
 
-        protected override DateTime CompareDate(BaseItem item)
+        protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
         {
-            var xml = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "game.xml"));
-            return xml != null ? FileSystem.GetLastWriteTimeUtc(xml, Logger) : DateTime.MinValue;
+            var savePath = GameXmlSaver.GetGameSavePath(item);
+
+            var xml = item.ResolveArgs.GetMetaFileByPath(savePath) ?? new FileInfo(savePath);
+
+            if (!xml.Exists)
+            {
+                return false;
+            }
+
+            return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
         }
 
         /// <summary>
@@ -61,21 +70,17 @@ namespace MediaBrowser.Providers.Games
         {
             cancellationToken.ThrowIfCancellationRequested();
 
-            var metaFile = Path.Combine(game.MetaLocation, "game.xml");
+            var metaFile = GameXmlSaver.GetGameSavePath(game);
 
-            if (File.Exists(metaFile))
-            {
-                await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
-
-                try
-                {
-                    new BaseItemXmlParser<Game>(Logger).Fetch(game, metaFile, cancellationToken);
-                }
-                finally
-                {
-                    XmlParsingResourcePool.Release();
-                }
+            await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
 
+            try
+            {
+                new BaseItemXmlParser<Game>(Logger).Fetch(game, metaFile, cancellationToken);
+            }
+            finally
+            {
+                XmlParsingResourcePool.Release();
             }
 
             SetLastRefreshed(game, DateTime.UtcNow);

+ 12 - 10
MediaBrowser.Providers/Games/GameSystemProviderFromXml.cs

@@ -1,5 +1,6 @@
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
@@ -39,16 +40,17 @@ namespace MediaBrowser.Providers.Games
             get { return MetadataProviderPriority.First; }
         }
 
-        /// <summary>
-        /// Override this to return the date that should be compared to the last refresh date
-        /// to determine if this provider should be re-fetched.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns>DateTime.</returns>
-        protected override DateTime CompareDate(BaseItem item)
+        private const string XmlFileName = "gamesystem.xml";
+        protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
         {
-            var entry = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "gamesystem.xml"));
-            return entry != null ? entry.LastWriteTimeUtc : DateTime.MinValue;
+            var xml = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
+
+            if (xml == null)
+            {
+                return false;
+            }
+
+            return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
         }
 
         /// <summary>
@@ -73,7 +75,7 @@ namespace MediaBrowser.Providers.Games
         {
             cancellationToken.ThrowIfCancellationRequested();
 
-            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "gamesystem.xml"));
+            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
 
             if (metadataFile != null)
             {

+ 1 - 4
MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs

@@ -174,10 +174,7 @@ namespace MediaBrowser.Providers.MediaInfo
                     {
                         var parentPath = Path.GetDirectoryName(path);
 
-                        if (!Directory.Exists(parentPath))
-                        {
-                            Directory.CreateDirectory(parentPath);
-                        }
+                        Directory.CreateDirectory(parentPath);
 
                         await _mediaEncoder.ExtractImage(new[] { item.Path }, InputType.AudioFile, null, null, path, cancellationToken).ConfigureAwait(false);
                     }

+ 1 - 4
MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs

@@ -222,10 +222,7 @@ namespace MediaBrowser.Providers.MediaInfo
                     {
                         var parentPath = Path.GetDirectoryName(path);
 
-                        if (!Directory.Exists(parentPath))
-                        {
-                            Directory.CreateDirectory(parentPath);
-                        }
+                        Directory.CreateDirectory(parentPath);
 
                         await ExtractImageInternal(item, path, cancellationToken).ConfigureAwait(false);
                     }

+ 12 - 10
MediaBrowser.Providers/Movies/BoxSetProviderFromXml.cs

@@ -1,6 +1,7 @@
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
@@ -43,16 +44,17 @@ namespace MediaBrowser.Providers.Movies
             get { return MetadataProviderPriority.First; }
         }
 
-        /// <summary>
-        /// Override this to return the date that should be compared to the last refresh date
-        /// to determine if this provider should be re-fetched.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns>DateTime.</returns>
-        protected override DateTime CompareDate(BaseItem item)
+        private const string XmlFileName = "collection.xml";
+        protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
         {
-            var entry = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "collection.xml"));
-            return entry != null ? entry.LastWriteTimeUtc : DateTime.MinValue;
+            var xml = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
+
+            if (xml == null)
+            {
+                return false;
+            }
+
+            return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
         }
 
         /// <summary>
@@ -77,7 +79,7 @@ namespace MediaBrowser.Providers.Movies
         {
             cancellationToken.ThrowIfCancellationRequested();
 
-            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "collection.xml"));
+            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
 
             if (metadataFile != null)
             {

+ 13 - 16
MediaBrowser.Providers/Movies/FanArtMovieProvider.cs

@@ -168,14 +168,21 @@ namespace MediaBrowser.Providers.Movies
                 // Process images
                 var path = GetMovieDataPath(ConfigurationManager.ApplicationPaths, id);
 
-                var files = new DirectoryInfo(path)
-                    .EnumerateFiles("*.xml", SearchOption.TopDirectoryOnly)
-                    .Select(i => i.LastWriteTimeUtc)
-                    .ToList();
+                try
+                {
+                    var files = new DirectoryInfo(path)
+                        .EnumerateFiles("*.xml", SearchOption.TopDirectoryOnly)
+                        .Select(i => i.LastWriteTimeUtc)
+                        .ToList();
 
-                if (files.Count > 0)
+                    if (files.Count > 0)
+                    {
+                        return files.Max();
+                    }
+                }
+                catch (DirectoryNotFoundException)
                 {
-                    return files.Max();
+                    // Don't blow up
                 }
             }
 
@@ -192,11 +199,6 @@ namespace MediaBrowser.Providers.Movies
         {
             var dataPath = Path.Combine(GetMoviesDataPath(appPaths), tmdbId);
 
-            if (!Directory.Exists(dataPath))
-            {
-                Directory.CreateDirectory(dataPath);
-            }
-
             return dataPath;
         }
 
@@ -209,11 +211,6 @@ namespace MediaBrowser.Providers.Movies
         {
             var dataPath = Path.Combine(appPaths.DataPath, "fanart-movies");
 
-            if (!Directory.Exists(dataPath))
-            {
-                Directory.CreateDirectory(dataPath);
-            }
-
             return dataPath;
         }
 

+ 3 - 4
MediaBrowser.Providers/Movies/FanArtMovieUpdatesPrescanTask.cs

@@ -59,6 +59,8 @@ namespace MediaBrowser.Providers.Movies
 
             var path = FanArtMovieProvider.GetMoviesDataPath(_config.CommonApplicationPaths);
 
+            Directory.CreateDirectory(path);
+            
             var timestampFile = Path.Combine(path, "time.txt");
 
             var timestampFileInfo = new FileInfo(timestampFile);
@@ -146,10 +148,7 @@ namespace MediaBrowser.Providers.Movies
 
             movieDataPath = Path.Combine(movieDataPath, tmdbId);
 
-            if (!Directory.Exists(movieDataPath))
-            {
-                Directory.CreateDirectory(movieDataPath);
-            }
+            Directory.CreateDirectory(movieDataPath);
 
             return FanArtMovieProvider.Current.DownloadMovieXml(movieDataPath, tmdbId, cancellationToken);
         }

+ 9 - 2
MediaBrowser.Providers/Movies/MovieDbProvider.cs

@@ -15,6 +15,7 @@ using System.Net;
 using System.Text.RegularExpressions;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Providers.Savers;
 
 namespace MediaBrowser.Providers.Movies
 {
@@ -233,9 +234,15 @@ namespace MediaBrowser.Providers.Movies
                 return item.LocationType == LocationType.FileSystem && item.ResolveArgs.ContainsMetaFileByName("collection.xml");
             }
 
-            var xmlFileName = MovieProviderFromXml.GetXmlFilename(item);
+            var path = MovieXmlSaver.GetMovieSavePath(item);
 
-            return item.LocationType == LocationType.FileSystem && item.ResolveArgs.ContainsMetaFileByName(xmlFileName);
+            if (item.LocationType == LocationType.FileSystem)
+            {
+                // If mixed with multiple movies in one folder, resolve args won't have the file system children
+                return item.ResolveArgs.ContainsMetaFileByName(Path.GetFileName(path)) || File.Exists(path);
+            }
+
+            return false;
         }
 
         /// <summary>

+ 24 - 33
MediaBrowser.Providers/Movies/MovieProviderFromXml.cs

@@ -1,9 +1,11 @@
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Logging;
+using MediaBrowser.Providers.Savers;
 using System;
 using System.IO;
 using System.Threading;
@@ -52,23 +54,18 @@ namespace MediaBrowser.Providers.Movies
             get { return MetadataProviderPriority.First; }
         }
 
-        internal static string GetXmlFilename(BaseItem item)
+        protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
         {
-            const string filename = "movie.xml";
+            var savePath = MovieXmlSaver.GetMovieSavePath(item);
 
-            return Path.Combine(item.MetaLocation, filename);
-        }
+            var xml = item.ResolveArgs.GetMetaFileByPath(savePath) ?? new FileInfo(savePath);
 
-        /// <summary>
-        /// Override this to return the date that should be compared to the last refresh date
-        /// to determine if this provider should be re-fetched.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns>DateTime.</returns>
-        protected override DateTime CompareDate(BaseItem item)
-        {
-            var entry = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, GetXmlFilename(item)));
-            return entry != null ? entry.LastWriteTimeUtc : DateTime.MinValue;
+            if (!xml.Exists)
+            {
+                return false;
+            }
+
+            return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
         }
 
         /// <summary>
@@ -93,30 +90,24 @@ namespace MediaBrowser.Providers.Movies
         {
             cancellationToken.ThrowIfCancellationRequested();
 
-            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, GetXmlFilename(item)));
+            var path = MovieXmlSaver.GetMovieSavePath(item);
 
-            if (metadataFile != null)
-            {
-                var path = metadataFile.FullName;
-
-                await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
+            await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
 
-                try
-                {
-                    var video = (Video) item;
-
-                    await new MovieXmlParser(Logger, _itemRepo).FetchAsync(video, path, cancellationToken).ConfigureAwait(false);
-                }
-                finally
-                {
-                    XmlParsingResourcePool.Release();
-                }
+            try
+            {
+                var video = (Video)item;
 
-                SetLastRefreshed(item, DateTime.UtcNow);
-                return true;
+                await new MovieXmlParser(Logger, _itemRepo).FetchAsync(video, path, cancellationToken).ConfigureAwait(false);
             }
+            finally
+            {
+                XmlParsingResourcePool.Release();
+            }
+
+            SetLastRefreshed(item, DateTime.UtcNow);
 
-            return false;
+            return true;
         }
     }
 }

+ 12 - 10
MediaBrowser.Providers/Movies/PersonProviderFromXml.cs

@@ -1,5 +1,6 @@
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Logging;
 using System;
@@ -38,16 +39,17 @@ namespace MediaBrowser.Providers.Movies
             get { return MetadataProviderPriority.Second; }
         }
 
-        /// <summary>
-        /// Override this to return the date that should be compared to the last refresh date
-        /// to determine if this provider should be re-fetched.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns>DateTime.</returns>
-        protected override DateTime CompareDate(BaseItem item)
+        private const string XmlFileName = "person.xml";
+        protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
         {
-            var entry = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "person.xml"));
-            return entry != null ? entry.LastWriteTimeUtc : DateTime.MinValue;
+            var xml = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
+
+            if (xml == null)
+            {
+                return false;
+            }
+
+            return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
         }
 
         /// <summary>
@@ -72,7 +74,7 @@ namespace MediaBrowser.Providers.Movies
         {
             cancellationToken.ThrowIfCancellationRequested();
 
-            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "person.xml"));
+            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
 
             if (metadataFile != null)
             {

+ 12 - 10
MediaBrowser.Providers/Music/ArtistProviderFromXml.cs

@@ -1,6 +1,7 @@
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
@@ -40,16 +41,17 @@ namespace MediaBrowser.Providers.Music
             get { return MetadataProviderPriority.First; }
         }
 
-        /// <summary>
-        /// Override this to return the date that should be compared to the last refresh date
-        /// to determine if this provider should be re-fetched.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns>DateTime.</returns>
-        protected override DateTime CompareDate(BaseItem item)
+        private const string XmlFileName = "artist.xml";
+        protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
         {
-            var entry = item.MetaLocation != null ? item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "artist.xml")) : null;
-            return entry != null ? entry.LastWriteTimeUtc : DateTime.MinValue;
+            var xml = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
+
+            if (xml == null)
+            {
+                return false;
+            }
+
+            return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
         }
 
         /// <summary>
@@ -74,7 +76,7 @@ namespace MediaBrowser.Providers.Music
         {
             cancellationToken.ThrowIfCancellationRequested();
 
-            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "artist.xml"));
+            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
 
             if (metadataFile != null)
             {

+ 13 - 16
MediaBrowser.Providers/Music/FanArtArtistProvider.cs

@@ -163,14 +163,21 @@ namespace MediaBrowser.Providers.Music
                 // Process images
                 var path = GetArtistDataPath(ConfigurationManager.ApplicationPaths, musicBrainzId);
 
-                var files = new DirectoryInfo(path)
-                    .EnumerateFiles("*.xml", SearchOption.TopDirectoryOnly)
-                    .Select(i => i.LastWriteTimeUtc)
-                    .ToList();
+                try
+                {
+                    var files = new DirectoryInfo(path)
+                        .EnumerateFiles("*.xml", SearchOption.TopDirectoryOnly)
+                        .Select(i => i.LastWriteTimeUtc)
+                        .ToList();
 
-                if (files.Count > 0)
+                    if (files.Count > 0)
+                    {
+                        return files.Max();
+                    }
+                }
+                catch (DirectoryNotFoundException)
                 {
-                    return files.Max();
+                    
                 }
             }
 
@@ -192,11 +199,6 @@ namespace MediaBrowser.Providers.Music
         {
             var seriesDataPath = Path.Combine(GetArtistDataPath(appPaths), musicBrainzArtistId);
 
-            if (!Directory.Exists(seriesDataPath))
-            {
-                Directory.CreateDirectory(seriesDataPath);
-            }
-
             return seriesDataPath;
         }
 
@@ -209,11 +211,6 @@ namespace MediaBrowser.Providers.Music
         {
             var dataPath = Path.Combine(appPaths.DataPath, "fanart-music");
 
-            if (!Directory.Exists(dataPath))
-            {
-                Directory.CreateDirectory(dataPath);
-            }
-
             return dataPath;
         }
 

+ 3 - 4
MediaBrowser.Providers/Music/FanArtUpdatesPrescanTask.cs

@@ -58,6 +58,8 @@ namespace MediaBrowser.Providers.Music
 
             var path = FanArtArtistProvider.GetArtistDataPath(_config.CommonApplicationPaths);
 
+            Directory.CreateDirectory(path);
+
             var timestampFile = Path.Combine(path, "time.txt");
 
             var timestampFileInfo = new FileInfo(timestampFile);
@@ -167,10 +169,7 @@ namespace MediaBrowser.Providers.Music
 
             artistsDataPath = Path.Combine(artistsDataPath, musicBrainzId);
 
-            if (!Directory.Exists(artistsDataPath))
-            {
-                Directory.CreateDirectory(artistsDataPath);
-            }
+            Directory.CreateDirectory(artistsDataPath);
 
             return FanArtArtistProvider.Current.DownloadArtistXml(artistsDataPath, musicBrainzId, cancellationToken);
         }

+ 12 - 2
MediaBrowser.Providers/Savers/GameXmlSaver.cs

@@ -1,9 +1,9 @@
-using System.Collections.Generic;
-using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Providers.Movies;
 using System;
+using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using System.Security;
@@ -88,6 +88,16 @@ namespace MediaBrowser.Providers.Savers
 
         public string GetSavePath(BaseItem item)
         {
+            return GetGameSavePath(item);
+        }
+
+        public static string GetGameSavePath(BaseItem item)
+        {
+            if (item.IsInMixedFolder)
+            {
+                return Path.ChangeExtension(item.Path, ".xml");
+            }
+
             return Path.Combine(item.MetaLocation, "game.xml");
         }
     }

+ 15 - 3
MediaBrowser.Providers/Savers/MovieXmlSaver.cs

@@ -1,11 +1,11 @@
-using System.Collections.Generic;
-using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Providers.Movies;
 using System;
+using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using System.Security;
@@ -117,13 +117,25 @@ namespace MediaBrowser.Providers.Savers
         }
 
         public string GetSavePath(BaseItem item)
+        {
+            return GetMovieSavePath(item);
+        }
+
+        public static string GetMovieSavePath(BaseItem item)
         {
             if (item.IsInMixedFolder)
             {
                 return Path.ChangeExtension(item.Path, ".xml");
             }
 
-            var filename = MovieProviderFromXml.GetXmlFilename(item);
+            var filename = GetXmlFilename(item);
+
+            return Path.Combine(item.MetaLocation, filename);
+        }
+
+        private static string GetXmlFilename(BaseItem item)
+        {
+            const string filename = "movie.xml";
 
             return Path.Combine(item.MetaLocation, filename);
         }

+ 1 - 4
MediaBrowser.Providers/Savers/XmlSaverHelpers.cs

@@ -98,10 +98,7 @@ namespace MediaBrowser.Providers.Savers
 
             var parentPath = Path.GetDirectoryName(path);
 
-            if (!Directory.Exists(parentPath))
-            {
-                Directory.CreateDirectory(parentPath);
-            }
+            Directory.CreateDirectory(parentPath);
 
             var wasHidden = false;
 

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

@@ -90,7 +90,7 @@ namespace MediaBrowser.Providers.TV
 
             var parent = item.ResolveArgs.Parent;
 
-            ValidateImage(episode, item.MetaLocation);
+            ValidateImage(episode);
 
             cancellationToken.ThrowIfCancellationRequested();
 
@@ -106,7 +106,7 @@ namespace MediaBrowser.Providers.TV
         /// <param name="episode">The episode.</param>
         /// <param name="metadataFolderPath">The metadata folder path.</param>
         /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
-        private void ValidateImage(Episode episode, string metadataFolderPath)
+        private void ValidateImage(Episode episode)
         {
             var path = episode.PrimaryImagePath;
 

+ 7 - 6
MediaBrowser.Providers/TV/EpisodeProviderFromXml.cs

@@ -1,6 +1,7 @@
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
@@ -59,12 +60,12 @@ namespace MediaBrowser.Providers.TV
         }
 
         /// <summary>
-        /// Override this to return the date that should be compared to the last refresh date
-        /// to determine if this provider should be re-fetched.
+        /// Needses the refresh based on compare date.
         /// </summary>
         /// <param name="item">The item.</param>
-        /// <returns>DateTime.</returns>
-        protected override DateTime CompareDate(BaseItem item)
+        /// <param name="providerInfo">The provider info.</param>
+        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
+        protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
         {
             var metadataFile = Path.Combine(item.MetaLocation, Path.ChangeExtension(Path.GetFileName(item.Path), ".xml"));
 
@@ -72,10 +73,10 @@ namespace MediaBrowser.Providers.TV
 
             if (file == null)
             {
-                return base.CompareDate(item);
+                return false;
             }
 
-            return file.LastWriteTimeUtc;
+            return FileSystem.GetLastWriteTimeUtc(file, Logger) > providerInfo.LastRefreshed;
         }
 
         /// <summary>

+ 13 - 16
MediaBrowser.Providers/TV/FanArtTVProvider.cs

@@ -100,14 +100,21 @@ namespace MediaBrowser.Providers.TV
                 // Process images
                 var path = GetSeriesDataPath(ConfigurationManager.ApplicationPaths, id);
 
-                var files = new DirectoryInfo(path)
-                    .EnumerateFiles("*.xml", SearchOption.TopDirectoryOnly)
-                    .Select(i => i.LastWriteTimeUtc)
-                    .ToList();
+                try
+                {
+                    var files = new DirectoryInfo(path)
+                        .EnumerateFiles("*.xml", SearchOption.TopDirectoryOnly)
+                        .Select(i => i.LastWriteTimeUtc)
+                        .ToList();
 
-                if (files.Count > 0)
+                    if (files.Count > 0)
+                    {
+                        return files.Max();
+                    }
+                }
+                catch (DirectoryNotFoundException)
                 {
-                    return files.Max();
+                    // Don't blow up
                 }
             }
 
@@ -148,11 +155,6 @@ namespace MediaBrowser.Providers.TV
         {
             var seriesDataPath = Path.Combine(GetSeriesDataPath(appPaths), seriesId);
 
-            if (!Directory.Exists(seriesDataPath))
-            {
-                Directory.CreateDirectory(seriesDataPath);
-            }
-
             return seriesDataPath;
         }
 
@@ -165,11 +167,6 @@ namespace MediaBrowser.Providers.TV
         {
             var dataPath = Path.Combine(appPaths.DataPath, "fanart-tv");
 
-            if (!Directory.Exists(dataPath))
-            {
-                Directory.CreateDirectory(dataPath);
-            }
-
             return dataPath;
         }
         

+ 3 - 4
MediaBrowser.Providers/TV/FanArtTvUpdatesPrescanTask.cs

@@ -59,6 +59,8 @@ namespace MediaBrowser.Providers.TV
 
             var path = FanArtTvProvider.GetSeriesDataPath(_config.CommonApplicationPaths);
 
+            Directory.CreateDirectory(path);
+            
             var timestampFile = Path.Combine(path, "time.txt");
 
             var timestampFileInfo = new FileInfo(timestampFile);
@@ -161,10 +163,7 @@ namespace MediaBrowser.Providers.TV
 
             seriesDataPath = Path.Combine(seriesDataPath, tvdbId);
 
-            if (!Directory.Exists(seriesDataPath))
-            {
-                Directory.CreateDirectory(seriesDataPath);
-            }
+            Directory.CreateDirectory(seriesDataPath);
 
             return FanArtTvProvider.Current.DownloadSeriesXml(seriesDataPath, tvdbId, cancellationToken);
         }

+ 13 - 16
MediaBrowser.Providers/TV/RemoteSeriesProvider.cs

@@ -171,14 +171,21 @@ namespace MediaBrowser.Providers.TV
                 // Process images
                 var path = GetSeriesDataPath(ConfigurationManager.ApplicationPaths, seriesId);
 
-                var files = new DirectoryInfo(path)
-                    .EnumerateFiles("*.xml", SearchOption.TopDirectoryOnly)
-                    .Select(i => i.LastWriteTimeUtc)
-                    .ToList();
+                try
+                {
+                    var files = new DirectoryInfo(path)
+                        .EnumerateFiles("*.xml", SearchOption.TopDirectoryOnly)
+                        .Select(i => i.LastWriteTimeUtc)
+                        .ToList();
 
-                if (files.Count > 0)
+                    if (files.Count > 0)
+                    {
+                        return files.Max();
+                    }
+                }
+                catch (DirectoryNotFoundException)
                 {
-                    return files.Max();
+                    // Don't blow up
                 }
             }
 
@@ -299,11 +306,6 @@ namespace MediaBrowser.Providers.TV
         {
             var seriesDataPath = Path.Combine(GetSeriesDataPath(appPaths), seriesId);
 
-            if (!Directory.Exists(seriesDataPath))
-            {
-                Directory.CreateDirectory(seriesDataPath);
-            }
-
             return seriesDataPath;
         }
 
@@ -316,11 +318,6 @@ namespace MediaBrowser.Providers.TV
         {
             var dataPath = Path.Combine(appPaths.DataPath, "tvdb");
 
-            if (!Directory.Exists(dataPath))
-            {
-                Directory.CreateDirectory(dataPath);
-            }
-
             return dataPath;
         }
 

+ 12 - 10
MediaBrowser.Providers/TV/SeasonProviderFromXml.cs

@@ -1,6 +1,7 @@
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
@@ -43,16 +44,17 @@ namespace MediaBrowser.Providers.TV
             get { return MetadataProviderPriority.First; }
         }
 
-        /// <summary>
-        /// Override this to return the date that should be compared to the last refresh date
-        /// to determine if this provider should be re-fetched.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns>DateTime.</returns>
-        protected override DateTime CompareDate(BaseItem item)
+        private const string XmlFileName = "season.xml";
+        protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
         {
-            var entry = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "season.xml"));
-            return entry != null ? entry.LastWriteTimeUtc : DateTime.MinValue;
+            var xml = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
+
+            if (xml == null)
+            {
+                return false;
+            }
+
+            return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
         }
 
         /// <summary>
@@ -77,7 +79,7 @@ namespace MediaBrowser.Providers.TV
         {
             cancellationToken.ThrowIfCancellationRequested();
 
-            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "season.xml"));
+            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
 
             if (metadataFile != null)
             {

+ 13 - 11
MediaBrowser.Providers/TV/SeriesProviderFromXml.cs

@@ -1,13 +1,14 @@
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
 using System;
 using System.IO;
 using System.Threading;
 using System.Threading.Tasks;
-using MediaBrowser.Model.Logging;
 
 namespace MediaBrowser.Providers.TV
 {
@@ -43,16 +44,17 @@ namespace MediaBrowser.Providers.TV
             get { return MetadataProviderPriority.First; }
         }
 
-        /// <summary>
-        /// Override this to return the date that should be compared to the last refresh date
-        /// to determine if this provider should be re-fetched.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns>DateTime.</returns>
-        protected override DateTime CompareDate(BaseItem item)
+        private const string XmlFileName = "series.xml";
+        protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
         {
-            var entry = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "series.xml"));
-            return entry != null ? entry.LastWriteTimeUtc : DateTime.MinValue;
+            var xml = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
+
+            if (xml == null)
+            {
+                return false;
+            }
+
+            return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
         }
 
         /// <summary>
@@ -77,7 +79,7 @@ namespace MediaBrowser.Providers.TV
         {
             cancellationToken.ThrowIfCancellationRequested();
             
-            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "series.xml"));
+            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
 
             if (metadataFile != null)
             {

+ 3 - 4
MediaBrowser.Providers/TV/TvdbPrescanTask.cs

@@ -71,6 +71,8 @@ namespace MediaBrowser.Providers.TV
 
             var path = RemoteSeriesProvider.GetSeriesDataPath(_config.CommonApplicationPaths);
 
+            Directory.CreateDirectory(path);
+            
             var timestampFile = Path.Combine(path, "time.txt");
 
             var timestampFileInfo = new FileInfo(timestampFile);
@@ -295,10 +297,7 @@ namespace MediaBrowser.Providers.TV
 
             seriesDataPath = Path.Combine(seriesDataPath, id);
 
-            if (!Directory.Exists(seriesDataPath))
-            {
-                Directory.CreateDirectory(seriesDataPath);
-            }
+            Directory.CreateDirectory(seriesDataPath);
 
             return RemoteSeriesProvider.Current.DownloadSeriesZip(id, seriesDataPath, cancellationToken);
         }

+ 4 - 16
MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs

@@ -225,10 +225,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
                 {
                     var parentPath = Path.GetDirectoryName(cacheFilePath);
 
-                    if (!Directory.Exists(parentPath))
-                    {
-                        Directory.CreateDirectory(parentPath);
-                    }
+                    Directory.CreateDirectory(parentPath);
 
                     // Save to the cache location
                     using (var cacheFileStream = new FileStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
@@ -374,10 +371,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
                             {
                                 var parentPath = Path.GetDirectoryName(croppedImagePath);
 
-                                if (!Directory.Exists(parentPath))
-                                {
-                                    Directory.CreateDirectory(parentPath);
-                                }
+                                Directory.CreateDirectory(parentPath);
 
                                 using (var outputStream = new FileStream(croppedImagePath, FileMode.Create, FileAccess.Write, FileShare.Read))
                                 {
@@ -528,10 +522,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
 
                 var parentPath = Path.GetDirectoryName(fullCachePath);
 
-                if (!Directory.Exists(parentPath))
-                {
-                    Directory.CreateDirectory(parentPath);
-                }
+                Directory.CreateDirectory(parentPath);
 
                 // Update the file system cache
                 File.WriteAllText(fullCachePath, size.Width.ToString(UsCulture) + @"|" + size.Height.ToString(UsCulture));
@@ -701,10 +692,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
                             {
                                 var parentDirectory = Path.GetDirectoryName(enhancedImagePath);
 
-                                if (!Directory.Exists(parentDirectory))
-                                {
-                                    Directory.CreateDirectory(parentDirectory);
-                                }
+                                Directory.CreateDirectory(parentDirectory);
 
                                 //And then save it in the cache
                                 using (var outputStream = new FileStream(enhancedImagePath, FileMode.Create, FileAccess.Write, FileShare.Read))

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

@@ -527,16 +527,13 @@ namespace MediaBrowser.Server.Implementations.Library
             {
                 try
                 {
-                    if (f.Exists)
-                    {
-                        var item = ResolvePath(f, parent) as T;
+                    var item = ResolvePath(f, parent) as T;
 
-                        if (item != null)
+                    if (item != null)
+                    {
+                        lock (list)
                         {
-                            lock (list)
-                            {
-                                list.Add(item);
-                            }
+                            list.Add(item);
                         }
                     }
                 }

+ 1 - 4
MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs

@@ -48,10 +48,7 @@ namespace MediaBrowser.Server.Implementations.Localization
 
             var localizationPath = LocalizationPath;
 
-            if (!Directory.Exists(localizationPath))
-            {
-                Directory.CreateDirectory(localizationPath);
-            }
+            Directory.CreateDirectory(localizationPath);
 
             var existingFiles = Directory.EnumerateFiles(localizationPath, "ratings-*.txt", SearchOption.TopDirectoryOnly)
                 .Select(Path.GetFileName)

+ 1 - 4
MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs

@@ -322,10 +322,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         /// <returns>Task.</returns>
         public Task SaveCriticReviews(Guid itemId, IEnumerable<ItemReview> criticReviews)
         {
-            if (!Directory.Exists(_criticReviewsPath))
-            {
-                Directory.CreateDirectory(_criticReviewsPath);
-            }
+            Directory.CreateDirectory(_criticReviewsPath);
 
             var path = Path.Combine(_criticReviewsPath, itemId + ".json");
 

+ 1 - 4
MediaBrowser.Server.Implementations/Providers/ImageSaver.cs

@@ -273,10 +273,7 @@ namespace MediaBrowser.Server.Implementations.Providers
 
             var parentPath = Path.GetDirectoryName(path);
 
-            if (!Directory.Exists(parentPath))
-            {
-                Directory.CreateDirectory(parentPath);
-            }
+            Directory.CreateDirectory(parentPath);
 
             return path;
         }

+ 1 - 4
MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs

@@ -182,10 +182,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
 
                     var parentPath = Path.GetDirectoryName(failHistoryPath);
 
-                    if (!Directory.Exists(parentPath))
-                    {
-                        Directory.CreateDirectory(parentPath);
-                    }
+                    Directory.CreateDirectory(parentPath);
 
                     File.WriteAllText(failHistoryPath, string.Join("|", previouslyFailedImages.ToArray()));
                 }

+ 4 - 16
MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs

@@ -55,10 +55,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg
                 Version = Version
             };
 
-            if (!Directory.Exists(versionedDirectoryPath))
-            {
-                Directory.CreateDirectory(versionedDirectoryPath);
-            }
+            Directory.CreateDirectory(versionedDirectoryPath);
 
             var tasks = new List<Task>();
 
@@ -114,10 +111,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg
 
             var tempFolder = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString());
 
-            if (!Directory.Exists(tempFolder))
-            {
-                Directory.CreateDirectory(tempFolder);
-            }
+            Directory.CreateDirectory(tempFolder);
 
             try
             {
@@ -163,10 +157,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg
             {
                 var fontsDirectory = Path.Combine(targetPath, "fonts");
 
-                if (!Directory.Exists(fontsDirectory))
-                {
-                    Directory.CreateDirectory(fontsDirectory);
-                }
+                Directory.CreateDirectory(fontsDirectory);
 
                 const string fontFilename = "ARIALUNI.TTF";
 
@@ -291,10 +282,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg
         {
             var path = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg");
 
-            if (create && !Directory.Exists(path))
-            {
-                Directory.CreateDirectory(path);
-            }
+            Directory.CreateDirectory(path);
 
             return path;
         }