mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-11-01 19:17:23 -04:00 
			
		
		
		
	Created ILibraryMonitor to replace IDirectoryWatchers
This commit is contained in:
		
							parent
							
								
									2ae17a8d52
								
							
						
					
					
						commit
						7c5b222463
					
				| @ -187,7 +187,7 @@ namespace MediaBrowser.Api.Library | ||||
|         /// </summary> | ||||
|         private readonly ILibraryManager _libraryManager; | ||||
| 
 | ||||
|         private readonly IDirectoryWatchers _directoryWatchers; | ||||
|         private readonly ILibraryMonitor _libraryMonitor; | ||||
| 
 | ||||
|         private readonly IFileSystem _fileSystem; | ||||
|         private readonly ILogger _logger; | ||||
| @ -199,7 +199,7 @@ namespace MediaBrowser.Api.Library | ||||
|         /// <param name="userManager">The user manager.</param> | ||||
|         /// <param name="libraryManager">The library manager.</param> | ||||
|         /// <exception cref="System.ArgumentNullException">appPaths</exception> | ||||
|         public LibraryStructureService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IDirectoryWatchers directoryWatchers, IFileSystem fileSystem, ILogger logger) | ||||
|         public LibraryStructureService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IFileSystem fileSystem, ILogger logger) | ||||
|         { | ||||
|             if (appPaths == null) | ||||
|             { | ||||
| @ -209,7 +209,7 @@ namespace MediaBrowser.Api.Library | ||||
|             _userManager = userManager; | ||||
|             _appPaths = appPaths; | ||||
|             _libraryManager = libraryManager; | ||||
|             _directoryWatchers = directoryWatchers; | ||||
|             _libraryMonitor = libraryMonitor; | ||||
|             _fileSystem = fileSystem; | ||||
|             _logger = logger; | ||||
|         } | ||||
| @ -270,8 +270,7 @@ namespace MediaBrowser.Api.Library | ||||
|                 throw new ArgumentException("There is already a media collection with the name " + name + "."); | ||||
|             } | ||||
| 
 | ||||
|             _directoryWatchers.Stop(); | ||||
|             _directoryWatchers.TemporarilyIgnore(virtualFolderPath); | ||||
|             _libraryMonitor.Stop(); | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
| @ -294,10 +293,8 @@ namespace MediaBrowser.Api.Library | ||||
|                 // No need to start if scanning the library because it will handle it | ||||
|                 if (!request.RefreshLibrary) | ||||
|                 { | ||||
|                     _directoryWatchers.Start(); | ||||
|                     _libraryMonitor.Start(); | ||||
|                 } | ||||
| 
 | ||||
|                 _directoryWatchers.RemoveTempIgnore(virtualFolderPath); | ||||
|             } | ||||
| 
 | ||||
|             if (request.RefreshLibrary) | ||||
| @ -348,9 +345,7 @@ namespace MediaBrowser.Api.Library | ||||
|                 throw new ArgumentException("There is already a media collection with the name " + newPath + "."); | ||||
|             } | ||||
| 
 | ||||
|             _directoryWatchers.Stop(); | ||||
|             _directoryWatchers.TemporarilyIgnore(currentPath); | ||||
|             _directoryWatchers.TemporarilyIgnore(newPath); | ||||
|             _libraryMonitor.Stop(); | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
| @ -376,11 +371,8 @@ namespace MediaBrowser.Api.Library | ||||
|                 // No need to start if scanning the library because it will handle it | ||||
|                 if (!request.RefreshLibrary) | ||||
|                 { | ||||
|                     _directoryWatchers.Start(); | ||||
|                     _libraryMonitor.Start(); | ||||
|                 } | ||||
| 
 | ||||
|                 _directoryWatchers.RemoveTempIgnore(currentPath); | ||||
|                 _directoryWatchers.RemoveTempIgnore(newPath); | ||||
|             } | ||||
| 
 | ||||
|             if (request.RefreshLibrary) | ||||
| @ -420,8 +412,7 @@ namespace MediaBrowser.Api.Library | ||||
|                 throw new DirectoryNotFoundException("The media folder does not exist"); | ||||
|             } | ||||
| 
 | ||||
|             _directoryWatchers.Stop(); | ||||
|             _directoryWatchers.TemporarilyIgnore(path); | ||||
|             _libraryMonitor.Stop(); | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
| @ -437,10 +428,8 @@ namespace MediaBrowser.Api.Library | ||||
|                 // No need to start if scanning the library because it will handle it | ||||
|                 if (!request.RefreshLibrary) | ||||
|                 { | ||||
|                     _directoryWatchers.Start(); | ||||
|                     _libraryMonitor.Start(); | ||||
|                 } | ||||
| 
 | ||||
|                 _directoryWatchers.RemoveTempIgnore(path); | ||||
|             } | ||||
| 
 | ||||
|             if (request.RefreshLibrary) | ||||
| @ -460,7 +449,7 @@ namespace MediaBrowser.Api.Library | ||||
|                 throw new ArgumentNullException("request"); | ||||
|             } | ||||
| 
 | ||||
|             _directoryWatchers.Stop(); | ||||
|             _libraryMonitor.Stop(); | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
| @ -485,7 +474,7 @@ namespace MediaBrowser.Api.Library | ||||
|                 // No need to start if scanning the library because it will handle it | ||||
|                 if (!request.RefreshLibrary) | ||||
|                 { | ||||
|                     _directoryWatchers.Start(); | ||||
|                     _libraryMonitor.Start(); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
| @ -506,7 +495,7 @@ namespace MediaBrowser.Api.Library | ||||
|                 throw new ArgumentNullException("request"); | ||||
|             } | ||||
| 
 | ||||
|             _directoryWatchers.Stop(); | ||||
|             _libraryMonitor.Stop(); | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
| @ -531,7 +520,7 @@ namespace MediaBrowser.Api.Library | ||||
|                 // No need to start if scanning the library because it will handle it | ||||
|                 if (!request.RefreshLibrary) | ||||
|                 { | ||||
|                     _directoryWatchers.Start(); | ||||
|                     _libraryMonitor.Start(); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  | ||||
| @ -1,29 +0,0 @@ | ||||
| using System; | ||||
| 
 | ||||
| namespace MediaBrowser.Controller.IO | ||||
| { | ||||
|     public interface IDirectoryWatchers : IDisposable | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Add the path to our temporary ignore list.  Use when writing to a path within our listening scope. | ||||
|         /// </summary> | ||||
|         /// <param name="path">The path.</param> | ||||
|         void TemporarilyIgnore(string path); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Removes the temp ignore. | ||||
|         /// </summary> | ||||
|         /// <param name="path">The path.</param> | ||||
|         void RemoveTempIgnore(string path); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Starts this instance. | ||||
|         /// </summary> | ||||
|         void Start(); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Stops this instance. | ||||
|         /// </summary> | ||||
|         void Stop(); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										36
									
								
								MediaBrowser.Controller/Library/ILibraryMonitor.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								MediaBrowser.Controller/Library/ILibraryMonitor.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | ||||
| using System; | ||||
| 
 | ||||
| namespace MediaBrowser.Controller.Library | ||||
| { | ||||
|     public interface ILibraryMonitor : IDisposable | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Starts this instance. | ||||
|         /// </summary> | ||||
|         void Start(); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Stops this instance. | ||||
|         /// </summary> | ||||
|         void Stop(); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Reports the file system change beginning. | ||||
|         /// </summary> | ||||
|         /// <param name="path">The path.</param> | ||||
|         void ReportFileSystemChangeBeginning(string path); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Reports the file system change complete. | ||||
|         /// </summary> | ||||
|         /// <param name="path">The path.</param> | ||||
|         /// <param name="refreshPath">if set to <c>true</c> [refresh path].</param> | ||||
|         void ReportFileSystemChangeComplete(string path, bool refreshPath); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Reports the file system changed. | ||||
|         /// </summary> | ||||
|         /// <param name="path">The path.</param> | ||||
|         void ReportFileSystemChanged(string path); | ||||
|     } | ||||
| } | ||||
| @ -182,7 +182,7 @@ | ||||
|     <Compile Include="Entities\Video.cs" /> | ||||
|     <Compile Include="Entities\CollectionFolder.cs" /> | ||||
|     <Compile Include="Entities\Year.cs" /> | ||||
|     <Compile Include="IO\IDirectoryWatchers.cs" /> | ||||
|     <Compile Include="Library\ILibraryMonitor.cs" /> | ||||
|     <Compile Include="IServerApplicationHost.cs" /> | ||||
|     <Compile Include="IServerApplicationPaths.cs" /> | ||||
|     <Compile Include="Library\SearchHintInfo.cs" /> | ||||
|  | ||||
| @ -165,7 +165,7 @@ namespace MediaBrowser.Model.Configuration | ||||
|         /// different directories and files. | ||||
|         /// </summary> | ||||
|         /// <value>The file watcher delay.</value> | ||||
|         public int FileWatcherDelay { get; set; } | ||||
|         public int RealtimeWatcherDelay { get; set; } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets or sets a value indicating whether [enable dashboard response caching]. | ||||
| @ -250,7 +250,7 @@ namespace MediaBrowser.Model.Configuration | ||||
|             MaxResumePct = 90; | ||||
|             MinResumeDurationSeconds = Convert.ToInt32(TimeSpan.FromMinutes(5).TotalSeconds); | ||||
| 
 | ||||
|             FileWatcherDelay = 8; | ||||
|             RealtimeWatcherDelay = 20; | ||||
| 
 | ||||
|             RecentItemDays = 10; | ||||
| 
 | ||||
|  | ||||
| @ -3,7 +3,7 @@ using MediaBrowser.Controller.Configuration; | ||||
| using MediaBrowser.Controller.Entities; | ||||
| using MediaBrowser.Controller.Entities.Audio; | ||||
| using MediaBrowser.Controller.Entities.TV; | ||||
| using MediaBrowser.Controller.IO; | ||||
| using MediaBrowser.Controller.Library; | ||||
| using MediaBrowser.Model.Configuration; | ||||
| using MediaBrowser.Model.Entities; | ||||
| using MediaBrowser.Model.Logging; | ||||
| @ -36,7 +36,7 @@ namespace MediaBrowser.Providers.Manager | ||||
|         /// <summary> | ||||
|         /// The _directory watchers | ||||
|         /// </summary> | ||||
|         private readonly IDirectoryWatchers _directoryWatchers; | ||||
|         private readonly ILibraryMonitor _libraryMonitor; | ||||
|         private readonly IFileSystem _fileSystem; | ||||
|         private readonly ILogger _logger; | ||||
| 
 | ||||
| @ -44,11 +44,11 @@ namespace MediaBrowser.Providers.Manager | ||||
|         /// Initializes a new instance of the <see cref="ImageSaver"/> class. | ||||
|         /// </summary> | ||||
|         /// <param name="config">The config.</param> | ||||
|         /// <param name="directoryWatchers">The directory watchers.</param> | ||||
|         public ImageSaver(IServerConfigurationManager config, IDirectoryWatchers directoryWatchers, IFileSystem fileSystem, ILogger logger) | ||||
|         /// <param name="libraryMonitor">The directory watchers.</param> | ||||
|         public ImageSaver(IServerConfigurationManager config, ILibraryMonitor libraryMonitor, IFileSystem fileSystem, ILogger logger) | ||||
|         { | ||||
|             _config = config; | ||||
|             _directoryWatchers = directoryWatchers; | ||||
|             _libraryMonitor = libraryMonitor; | ||||
|             _fileSystem = fileSystem; | ||||
|             _logger = logger; | ||||
|             _remoteImageCache = new FileSystemRepository(config.ApplicationPaths.DownloadedImagesDataPath); | ||||
| @ -160,7 +160,7 @@ namespace MediaBrowser.Providers.Manager | ||||
|             // Delete the current path | ||||
|             if (!string.IsNullOrEmpty(currentPath) && !paths.Contains(currentPath, StringComparer.OrdinalIgnoreCase)) | ||||
|             { | ||||
|                 _directoryWatchers.TemporarilyIgnore(currentPath); | ||||
|                 _libraryMonitor.ReportFileSystemChangeBeginning(currentPath); | ||||
| 
 | ||||
|                 try | ||||
|                 { | ||||
| @ -179,7 +179,7 @@ namespace MediaBrowser.Providers.Manager | ||||
|                 } | ||||
|                 finally | ||||
|                 { | ||||
|                     _directoryWatchers.RemoveTempIgnore(currentPath); | ||||
|                     _libraryMonitor.ReportFileSystemChangeComplete(currentPath, false); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @ -197,8 +197,8 @@ namespace MediaBrowser.Providers.Manager | ||||
| 
 | ||||
|             var parentFolder = Path.GetDirectoryName(path); | ||||
| 
 | ||||
|             _directoryWatchers.TemporarilyIgnore(path); | ||||
|             _directoryWatchers.TemporarilyIgnore(parentFolder); | ||||
|             _libraryMonitor.ReportFileSystemChangeBeginning(path); | ||||
|             _libraryMonitor.ReportFileSystemChangeBeginning(parentFolder); | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
| @ -223,8 +223,8 @@ namespace MediaBrowser.Providers.Manager | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 _directoryWatchers.RemoveTempIgnore(path); | ||||
|                 _directoryWatchers.RemoveTempIgnore(parentFolder); | ||||
|                 _libraryMonitor.ReportFileSystemChangeComplete(path, false); | ||||
|                 _libraryMonitor.ReportFileSystemChangeComplete(parentFolder, false); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -38,7 +38,6 @@ namespace MediaBrowser.Providers.Manager | ||||
|         public void AddParts(IEnumerable<IMetadataProvider> providers, IEnumerable<IImageProvider> imageProviders) | ||||
|         { | ||||
|             _providers = providers.OfType<IMetadataProvider<TItemType>>() | ||||
|                 .OrderBy(GetSortOrder) | ||||
|                 .ToArray(); | ||||
| 
 | ||||
|             _imageProviders = imageProviders.OrderBy(i => i.Order).ToArray(); | ||||
| @ -179,21 +178,6 @@ namespace MediaBrowser.Providers.Manager | ||||
|             return providers; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets the sort order. | ||||
|         /// </summary> | ||||
|         /// <param name="provider">The provider.</param> | ||||
|         /// <returns>System.Int32.</returns> | ||||
|         protected virtual int GetSortOrder(IMetadataProvider<TItemType> provider) | ||||
|         { | ||||
|             if (provider is IRemoteMetadataProvider) | ||||
|             { | ||||
|                 return 1; | ||||
|             } | ||||
| 
 | ||||
|             return 0; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Determines whether this instance can refresh the specified provider. | ||||
|         /// </summary> | ||||
| @ -217,7 +201,7 @@ namespace MediaBrowser.Providers.Manager | ||||
| 
 | ||||
|         protected abstract Task SaveItem(TItemType item, ItemUpdateType reason, CancellationToken cancellationToken); | ||||
| 
 | ||||
|         protected virtual ItemId GetId(TItemType item) | ||||
|         protected virtual ItemId GetId(IHasMetadata item) | ||||
|         { | ||||
|             return new ItemId | ||||
|             { | ||||
|  | ||||
| @ -36,7 +36,7 @@ namespace MediaBrowser.Providers.Manager | ||||
|         /// <summary> | ||||
|         /// The _directory watchers | ||||
|         /// </summary> | ||||
|         private readonly IDirectoryWatchers _directoryWatchers; | ||||
|         private readonly ILibraryMonitor _libraryMonitor; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets or sets the configuration manager. | ||||
| @ -57,23 +57,23 @@ namespace MediaBrowser.Providers.Manager | ||||
| 
 | ||||
|         private readonly IItemRepository _itemRepo; | ||||
| 
 | ||||
|         private IMetadataService[] _metadataServices = {}; | ||||
|         private IMetadataService[] _metadataServices = { }; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Initializes a new instance of the <see cref="ProviderManager" /> class. | ||||
|         /// </summary> | ||||
|         /// <param name="httpClient">The HTTP client.</param> | ||||
|         /// <param name="configurationManager">The configuration manager.</param> | ||||
|         /// <param name="directoryWatchers">The directory watchers.</param> | ||||
|         /// <param name="libraryMonitor">The directory watchers.</param> | ||||
|         /// <param name="logManager">The log manager.</param> | ||||
|         /// <param name="fileSystem">The file system.</param> | ||||
|         /// <param name="itemRepo">The item repo.</param> | ||||
|         public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, IDirectoryWatchers directoryWatchers, ILogManager logManager, IFileSystem fileSystem, IItemRepository itemRepo) | ||||
|         public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IItemRepository itemRepo) | ||||
|         { | ||||
|             _logger = logManager.GetLogger("ProviderManager"); | ||||
|             _httpClient = httpClient; | ||||
|             ConfigurationManager = configurationManager; | ||||
|             _directoryWatchers = directoryWatchers; | ||||
|             _libraryMonitor = libraryMonitor; | ||||
|             _fileSystem = fileSystem; | ||||
|             _itemRepo = itemRepo; | ||||
|         } | ||||
| @ -315,7 +315,7 @@ namespace MediaBrowser.Providers.Manager | ||||
|             } | ||||
| 
 | ||||
|             //Tell the watchers to ignore | ||||
|             _directoryWatchers.TemporarilyIgnore(path); | ||||
|             _libraryMonitor.ReportFileSystemChangeBeginning(path); | ||||
| 
 | ||||
|             if (dataToSave.CanSeek) | ||||
|             { | ||||
| @ -338,7 +338,7 @@ namespace MediaBrowser.Providers.Manager | ||||
|             finally | ||||
|             { | ||||
|                 //Remove the ignore | ||||
|                 _directoryWatchers.RemoveTempIgnore(path); | ||||
|                 _libraryMonitor.ReportFileSystemChangeComplete(path, false); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @ -380,7 +380,7 @@ namespace MediaBrowser.Providers.Manager | ||||
|         /// <returns>Task.</returns> | ||||
|         public Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, string sourceUrl, CancellationToken cancellationToken) | ||||
|         { | ||||
|             return new ImageSaver(ConfigurationManager, _directoryWatchers, _fileSystem, _logger).SaveImage(item, source, mimeType, type, imageIndex, sourceUrl, cancellationToken); | ||||
|             return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, source, mimeType, type, imageIndex, sourceUrl, cancellationToken); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | ||||
| @ -22,7 +22,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization | ||||
| { | ||||
|     public class EpisodeFileOrganizer | ||||
|     { | ||||
|         private readonly IDirectoryWatchers _directoryWatchers; | ||||
|         private readonly ILibraryMonitor _libraryMonitor; | ||||
|         private readonly ILibraryManager _libraryManager; | ||||
|         private readonly ILogger _logger; | ||||
|         private readonly IFileSystem _fileSystem; | ||||
| @ -31,14 +31,14 @@ namespace MediaBrowser.Server.Implementations.FileOrganization | ||||
| 
 | ||||
|         private readonly CultureInfo _usCulture = new CultureInfo("en-US"); | ||||
| 
 | ||||
|         public EpisodeFileOrganizer(IFileOrganizationService organizationService, IServerConfigurationManager config, IFileSystem fileSystem, ILogger logger, ILibraryManager libraryManager, IDirectoryWatchers directoryWatchers) | ||||
|         public EpisodeFileOrganizer(IFileOrganizationService organizationService, IServerConfigurationManager config, IFileSystem fileSystem, ILogger logger, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor) | ||||
|         { | ||||
|             _organizationService = organizationService; | ||||
|             _config = config; | ||||
|             _fileSystem = fileSystem; | ||||
|             _logger = logger; | ||||
|             _libraryManager = libraryManager; | ||||
|             _directoryWatchers = directoryWatchers; | ||||
|             _libraryMonitor = libraryMonitor; | ||||
|         } | ||||
| 
 | ||||
|         public async Task<FileOrganizationResult> OrganizeEpisodeFile(string path, TvFileOrganizationOptions options, bool overwriteExisting) | ||||
| @ -174,6 +174,8 @@ namespace MediaBrowser.Server.Implementations.FileOrganization | ||||
|                 { | ||||
|                     _logger.Debug("Removing duplicate episode {0}", path); | ||||
| 
 | ||||
|                     _libraryMonitor.ReportFileSystemChangeBeginning(path); | ||||
| 
 | ||||
|                     try | ||||
|                     { | ||||
|                         File.Delete(path); | ||||
| @ -182,6 +184,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization | ||||
|                     { | ||||
|                         _logger.ErrorException("Error removing duplicate episode", ex, path); | ||||
|                     } | ||||
|                     finally | ||||
|                     { | ||||
|                         _libraryMonitor.ReportFileSystemChangeComplete(path, true); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @ -232,7 +238,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization | ||||
| 
 | ||||
|         private void PerformFileSorting(TvFileOrganizationOptions options, FileOrganizationResult result) | ||||
|         { | ||||
|             _directoryWatchers.TemporarilyIgnore(result.TargetPath); | ||||
|             _libraryMonitor.ReportFileSystemChangeBeginning(result.TargetPath); | ||||
| 
 | ||||
|             Directory.CreateDirectory(Path.GetDirectoryName(result.TargetPath)); | ||||
| 
 | ||||
| @ -264,7 +270,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 _directoryWatchers.RemoveTempIgnore(result.TargetPath); | ||||
|                 _libraryMonitor.ReportFileSystemChangeComplete(result.TargetPath, true); | ||||
|             } | ||||
| 
 | ||||
|             if (copy) | ||||
|  | ||||
| @ -21,17 +21,17 @@ namespace MediaBrowser.Server.Implementations.FileOrganization | ||||
|         private readonly ITaskManager _taskManager; | ||||
|         private readonly IFileOrganizationRepository _repo; | ||||
|         private readonly ILogger _logger; | ||||
|         private readonly IDirectoryWatchers _directoryWatchers; | ||||
|         private readonly ILibraryMonitor _libraryMonitor; | ||||
|         private readonly ILibraryManager _libraryManager; | ||||
|         private readonly IServerConfigurationManager _config; | ||||
|         private readonly IFileSystem _fileSystem; | ||||
| 
 | ||||
|         public FileOrganizationService(ITaskManager taskManager, IFileOrganizationRepository repo, ILogger logger, IDirectoryWatchers directoryWatchers, ILibraryManager libraryManager, IServerConfigurationManager config, IFileSystem fileSystem) | ||||
|         public FileOrganizationService(ITaskManager taskManager, IFileOrganizationRepository repo, ILogger logger, ILibraryMonitor libraryMonitor, ILibraryManager libraryManager, IServerConfigurationManager config, IFileSystem fileSystem) | ||||
|         { | ||||
|             _taskManager = taskManager; | ||||
|             _repo = repo; | ||||
|             _logger = logger; | ||||
|             _directoryWatchers = directoryWatchers; | ||||
|             _libraryMonitor = libraryMonitor; | ||||
|             _libraryManager = libraryManager; | ||||
|             _config = config; | ||||
|             _fileSystem = fileSystem; | ||||
| @ -91,13 +91,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization | ||||
|             } | ||||
| 
 | ||||
|             var organizer = new EpisodeFileOrganizer(this, _config, _fileSystem, _logger, _libraryManager, | ||||
|                 _directoryWatchers); | ||||
|                 _libraryMonitor); | ||||
| 
 | ||||
|             await organizer.OrganizeEpisodeFile(result.OriginalPath, _config.Configuration.TvFileOrganizationOptions, true) | ||||
|                     .ConfigureAwait(false); | ||||
| 
 | ||||
|             await _libraryManager.ValidateMediaLibrary(new Progress<double>(), CancellationToken.None) | ||||
|                     .ConfigureAwait(false); | ||||
|         } | ||||
| 
 | ||||
|         public Task ClearLog() | ||||
| @ -108,12 +105,9 @@ namespace MediaBrowser.Server.Implementations.FileOrganization | ||||
|         public async Task PerformEpisodeOrganization(EpisodeFileOrganizationRequest request) | ||||
|         { | ||||
|             var organizer = new EpisodeFileOrganizer(this, _config, _fileSystem, _logger, _libraryManager, | ||||
|                 _directoryWatchers); | ||||
|                 _libraryMonitor); | ||||
| 
 | ||||
|             await organizer.OrganizeWithCorrection(request, _config.Configuration.TvFileOrganizationOptions).ConfigureAwait(false); | ||||
| 
 | ||||
|             await _libraryManager.ValidateMediaLibrary(new Progress<double>(), CancellationToken.None) | ||||
|                     .ConfigureAwait(false); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -14,16 +14,16 @@ namespace MediaBrowser.Server.Implementations.FileOrganization | ||||
| { | ||||
|     public class OrganizerScheduledTask : IScheduledTask, IConfigurableScheduledTask | ||||
|     { | ||||
|         private readonly IDirectoryWatchers _directoryWatchers; | ||||
|         private readonly ILibraryMonitor _libraryMonitor; | ||||
|         private readonly ILibraryManager _libraryManager; | ||||
|         private readonly ILogger _logger; | ||||
|         private readonly IFileSystem _fileSystem; | ||||
|         private readonly IServerConfigurationManager _config; | ||||
|         private readonly IFileOrganizationService _organizationService; | ||||
| 
 | ||||
|         public OrganizerScheduledTask(IDirectoryWatchers directoryWatchers, ILibraryManager libraryManager, ILogger logger, IFileSystem fileSystem, IServerConfigurationManager config, IFileOrganizationService organizationService) | ||||
|         public OrganizerScheduledTask(ILibraryMonitor libraryMonitor, ILibraryManager libraryManager, ILogger logger, IFileSystem fileSystem, IServerConfigurationManager config, IFileOrganizationService organizationService) | ||||
|         { | ||||
|             _directoryWatchers = directoryWatchers; | ||||
|             _libraryMonitor = libraryMonitor; | ||||
|             _libraryManager = libraryManager; | ||||
|             _logger = logger; | ||||
|             _fileSystem = fileSystem; | ||||
| @ -48,7 +48,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization | ||||
| 
 | ||||
|         public Task Execute(CancellationToken cancellationToken, IProgress<double> progress) | ||||
|         { | ||||
|             return new TvFolderOrganizer(_libraryManager, _logger, _fileSystem, _directoryWatchers, _organizationService, _config) | ||||
|             return new TvFolderOrganizer(_libraryManager, _logger, _fileSystem, _libraryMonitor, _organizationService, _config) | ||||
|                 .Organize(_config.Configuration.TvFileOrganizationOptions, cancellationToken, progress); | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -18,19 +18,19 @@ namespace MediaBrowser.Server.Implementations.FileOrganization | ||||
| { | ||||
|     public class TvFolderOrganizer | ||||
|     { | ||||
|         private readonly IDirectoryWatchers _directoryWatchers; | ||||
|         private readonly ILibraryMonitor _libraryMonitor; | ||||
|         private readonly ILibraryManager _libraryManager; | ||||
|         private readonly ILogger _logger; | ||||
|         private readonly IFileSystem _fileSystem; | ||||
|         private readonly IFileOrganizationService _organizationService; | ||||
|         private readonly IServerConfigurationManager _config; | ||||
| 
 | ||||
|         public TvFolderOrganizer(ILibraryManager libraryManager, ILogger logger, IFileSystem fileSystem, IDirectoryWatchers directoryWatchers, IFileOrganizationService organizationService, IServerConfigurationManager config) | ||||
|         public TvFolderOrganizer(ILibraryManager libraryManager, ILogger logger, IFileSystem fileSystem, ILibraryMonitor libraryMonitor, IFileOrganizationService organizationService, IServerConfigurationManager config) | ||||
|         { | ||||
|             _libraryManager = libraryManager; | ||||
|             _logger = logger; | ||||
|             _fileSystem = fileSystem; | ||||
|             _directoryWatchers = directoryWatchers; | ||||
|             _libraryMonitor = libraryMonitor; | ||||
|             _organizationService = organizationService; | ||||
|             _config = config; | ||||
|         } | ||||
| @ -57,7 +57,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization | ||||
|                 foreach (var file in eligibleFiles) | ||||
|                 { | ||||
|                     var organizer = new EpisodeFileOrganizer(_organizationService, _config, _fileSystem, _logger, _libraryManager, | ||||
|                         _directoryWatchers); | ||||
|                         _libraryMonitor); | ||||
| 
 | ||||
|                     var result = await organizer.OrganizeEpisodeFile(file.FullName, options, false).ConfigureAwait(false); | ||||
| 
 | ||||
|  | ||||
| @ -1,8 +1,6 @@ | ||||
| using MediaBrowser.Common.IO; | ||||
| using MediaBrowser.Common.ScheduledTasks; | ||||
| using MediaBrowser.Common.ScheduledTasks; | ||||
| using MediaBrowser.Controller.Configuration; | ||||
| using MediaBrowser.Controller.Entities; | ||||
| using MediaBrowser.Controller.IO; | ||||
| using MediaBrowser.Controller.Library; | ||||
| using MediaBrowser.Model.Entities; | ||||
| using MediaBrowser.Model.Logging; | ||||
| @ -18,10 +16,7 @@ using System.Threading.Tasks; | ||||
| 
 | ||||
| namespace MediaBrowser.Server.Implementations.IO | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Class DirectoryWatchers | ||||
|     /// </summary> | ||||
|     public class DirectoryWatchers : IDirectoryWatchers | ||||
|     public class LibraryMonitor : ILibraryMonitor | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// The file system watchers | ||||
| @ -55,7 +50,7 @@ namespace MediaBrowser.Server.Implementations.IO | ||||
|         /// Add the path to our temporary ignore list.  Use when writing to a path within our listening scope. | ||||
|         /// </summary> | ||||
|         /// <param name="path">The path.</param> | ||||
|         public void TemporarilyIgnore(string path) | ||||
|         private void TemporarilyIgnore(string path) | ||||
|         { | ||||
|             _tempIgnoredPaths[path] = path; | ||||
|         } | ||||
| @ -64,7 +59,7 @@ namespace MediaBrowser.Server.Implementations.IO | ||||
|         /// Removes the temp ignore. | ||||
|         /// </summary> | ||||
|         /// <param name="path">The path.</param> | ||||
|         public async void RemoveTempIgnore(string path) | ||||
|         private async void RemoveTempIgnore(string path) | ||||
|         { | ||||
|             // This is an arbitraty amount of time, but delay it because file system writes often trigger events after RemoveTempIgnore has been called.  | ||||
|             // Seeing long delays in some situations, especially over the network. | ||||
| @ -75,6 +70,21 @@ namespace MediaBrowser.Server.Implementations.IO | ||||
|             _tempIgnoredPaths.TryRemove(path, out val); | ||||
|         } | ||||
| 
 | ||||
|         public void ReportFileSystemChangeBeginning(string path) | ||||
|         { | ||||
|             TemporarilyIgnore(path); | ||||
|         } | ||||
| 
 | ||||
|         public void ReportFileSystemChangeComplete(string path, bool refreshPath) | ||||
|         { | ||||
|             RemoveTempIgnore(path); | ||||
| 
 | ||||
|             if (refreshPath) | ||||
|             { | ||||
|                 ReportFileSystemChanged(path); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets or sets the logger. | ||||
|         /// </summary> | ||||
| @ -90,12 +100,10 @@ namespace MediaBrowser.Server.Implementations.IO | ||||
|         private ILibraryManager LibraryManager { get; set; } | ||||
|         private IServerConfigurationManager ConfigurationManager { get; set; } | ||||
| 
 | ||||
|         private readonly IFileSystem _fileSystem; | ||||
|          | ||||
|         /// <summary> | ||||
|         /// Initializes a new instance of the <see cref="DirectoryWatchers" /> class. | ||||
|         /// Initializes a new instance of the <see cref="LibraryMonitor" /> class. | ||||
|         /// </summary> | ||||
|         public DirectoryWatchers(ILogManager logManager, ITaskManager taskManager, ILibraryManager libraryManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem) | ||||
|         public LibraryMonitor(ILogManager logManager, ITaskManager taskManager, ILibraryManager libraryManager, IServerConfigurationManager configurationManager) | ||||
|         { | ||||
|             if (taskManager == null) | ||||
|             { | ||||
| @ -104,9 +112,8 @@ namespace MediaBrowser.Server.Implementations.IO | ||||
| 
 | ||||
|             LibraryManager = libraryManager; | ||||
|             TaskManager = taskManager; | ||||
|             Logger = logManager.GetLogger("DirectoryWatchers"); | ||||
|             Logger = logManager.GetLogger(GetType().Name); | ||||
|             ConfigurationManager = configurationManager; | ||||
|             _fileSystem = fileSystem; | ||||
| 
 | ||||
|             SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; | ||||
|         } | ||||
| @ -328,31 +335,25 @@ namespace MediaBrowser.Server.Implementations.IO | ||||
|             { | ||||
|                 OnWatcherChanged(e); | ||||
|             } | ||||
|             catch (IOException ex) | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 Logger.ErrorException("IOException in watcher changed. Path: {0}", ex, e.FullPath); | ||||
|                 Logger.ErrorException("Exception in watcher changed. Path: {0}", ex, e.FullPath); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private void OnWatcherChanged(FileSystemEventArgs e) | ||||
|         { | ||||
|             var name = e.Name; | ||||
|             Logger.Debug("Watcher sees change of type " + e.ChangeType + " to " + e.FullPath); | ||||
| 
 | ||||
|             ReportFileSystemChanged(e.FullPath); | ||||
|         } | ||||
| 
 | ||||
|         public void ReportFileSystemChanged(string path) | ||||
|         { | ||||
|             var filename = Path.GetFileName(path); | ||||
| 
 | ||||
|             // Ignore certain files | ||||
|             if (_alwaysIgnoreFiles.Contains(name, StringComparer.OrdinalIgnoreCase)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             var nameFromFullPath = Path.GetFileName(e.FullPath); | ||||
|             // Ignore certain files | ||||
|             if (!string.IsNullOrEmpty(nameFromFullPath) && _alwaysIgnoreFiles.Contains(nameFromFullPath, StringComparer.OrdinalIgnoreCase)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             // Ignore when someone manually creates a new folder | ||||
|             if (e.ChangeType == WatcherChangeTypes.Created && name == "New folder") | ||||
|             if (!string.IsNullOrEmpty(filename) && _alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
| @ -362,17 +363,17 @@ namespace MediaBrowser.Server.Implementations.IO | ||||
|             // If the parent of an ignored path has a change event, ignore that too | ||||
|             if (tempIgnorePaths.Any(i => | ||||
|             { | ||||
|                 if (string.Equals(i, e.FullPath, StringComparison.OrdinalIgnoreCase)) | ||||
|                 if (string.Equals(i, path, StringComparison.OrdinalIgnoreCase)) | ||||
|                 { | ||||
|                     Logger.Debug("Watcher ignoring change to {0}", e.FullPath); | ||||
|                     Logger.Debug("Ignoring change to {0}", path); | ||||
|                     return true; | ||||
|                 } | ||||
| 
 | ||||
|                 // Go up a level | ||||
|                 var parent = Path.GetDirectoryName(i); | ||||
|                 if (string.Equals(parent, e.FullPath, StringComparison.OrdinalIgnoreCase)) | ||||
|                 if (string.Equals(parent, path, StringComparison.OrdinalIgnoreCase)) | ||||
|                 { | ||||
|                     Logger.Debug("Watcher ignoring change to {0}", e.FullPath); | ||||
|                     Logger.Debug("Ignoring change to {0}", path); | ||||
|                     return true; | ||||
|                 } | ||||
| 
 | ||||
| @ -380,17 +381,17 @@ namespace MediaBrowser.Server.Implementations.IO | ||||
|                 if (!string.IsNullOrEmpty(parent)) | ||||
|                 { | ||||
|                     parent = Path.GetDirectoryName(i); | ||||
|                     if (string.Equals(parent, e.FullPath, StringComparison.OrdinalIgnoreCase)) | ||||
|                     if (string.Equals(parent, path, StringComparison.OrdinalIgnoreCase)) | ||||
|                     { | ||||
|                         Logger.Debug("Watcher ignoring change to {0}", e.FullPath); | ||||
|                         Logger.Debug("Ignoring change to {0}", path); | ||||
|                         return true; | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 if (i.StartsWith(e.FullPath, StringComparison.OrdinalIgnoreCase) ||  | ||||
|                     e.FullPath.StartsWith(i, StringComparison.OrdinalIgnoreCase)) | ||||
|                 if (i.StartsWith(path, StringComparison.OrdinalIgnoreCase) || | ||||
|                     path.StartsWith(i, StringComparison.OrdinalIgnoreCase)) | ||||
|                 { | ||||
|                     Logger.Debug("Watcher ignoring change to {0}", e.FullPath); | ||||
|                     Logger.Debug("Ignoring change to {0}", path); | ||||
|                     return true; | ||||
|                 } | ||||
| 
 | ||||
| @ -401,22 +402,19 @@ namespace MediaBrowser.Server.Implementations.IO | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             Logger.Info("Watcher sees change of type " + e.ChangeType + " to " + e.FullPath); | ||||
| 
 | ||||
|             //Since we're watching created, deleted and renamed we always want the parent of the item to be the affected path | ||||
|             var affectedPath = e.FullPath; | ||||
| 
 | ||||
|             _affectedPaths.AddOrUpdate(affectedPath, affectedPath, (key, oldValue) => affectedPath); | ||||
|             // Avoid implicitly captured closure | ||||
|             var affectedPath = path; | ||||
|             _affectedPaths.AddOrUpdate(path, path, (key, oldValue) => affectedPath); | ||||
| 
 | ||||
|             lock (_timerLock) | ||||
|             { | ||||
|                 if (_updateTimer == null) | ||||
|                 { | ||||
|                     _updateTimer = new Timer(TimerStopped, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.FileWatcherDelay), TimeSpan.FromMilliseconds(-1)); | ||||
|                     _updateTimer = new Timer(TimerStopped, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.RealtimeWatcherDelay), TimeSpan.FromMilliseconds(-1)); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     _updateTimer.Change(TimeSpan.FromSeconds(ConfigurationManager.Configuration.FileWatcherDelay), TimeSpan.FromMilliseconds(-1)); | ||||
|                     _updateTimer.Change(TimeSpan.FromSeconds(ConfigurationManager.Configuration.RealtimeWatcherDelay), TimeSpan.FromMilliseconds(-1)); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @ -427,24 +425,9 @@ namespace MediaBrowser.Server.Implementations.IO | ||||
|         /// <param name="stateInfo">The state info.</param> | ||||
|         private async void TimerStopped(object stateInfo) | ||||
|         { | ||||
|             lock (_timerLock) | ||||
|             { | ||||
|                 // Extend the timer as long as any of the paths are still being written to. | ||||
|                 if (_affectedPaths.Any(p => IsFileLocked(p.Key))) | ||||
|                 { | ||||
|                     Logger.Info("Timer extended."); | ||||
|                     _updateTimer.Change(TimeSpan.FromSeconds(ConfigurationManager.Configuration.FileWatcherDelay), TimeSpan.FromMilliseconds(-1)); | ||||
|                     return; | ||||
|                 } | ||||
|             Logger.Debug("Timer stopped."); | ||||
| 
 | ||||
|                 Logger.Info("Timer stopped."); | ||||
| 
 | ||||
|                 if (_updateTimer != null) | ||||
|                 { | ||||
|                     _updateTimer.Dispose(); | ||||
|                     _updateTimer = null; | ||||
|                 } | ||||
|             } | ||||
|             DisposeTimer(); | ||||
| 
 | ||||
|             var paths = _affectedPaths.Keys.ToList(); | ||||
|             _affectedPaths.Clear(); | ||||
| @ -452,59 +435,16 @@ namespace MediaBrowser.Server.Implementations.IO | ||||
|             await ProcessPathChanges(paths).ConfigureAwait(false); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Try and determine if a file is locked | ||||
|         /// This is not perfect, and is subject to race conditions, so I'd rather not make this a re-usable library method. | ||||
|         /// </summary> | ||||
|         /// <param name="path">The path.</param> | ||||
|         /// <returns><c>true</c> if [is file locked] [the specified path]; otherwise, <c>false</c>.</returns> | ||||
|         private bool IsFileLocked(string path) | ||||
|         private void DisposeTimer() | ||||
|         { | ||||
|             try | ||||
|             lock (_timerLock) | ||||
|             { | ||||
|                 var data = _fileSystem.GetFileSystemInfo(path); | ||||
| 
 | ||||
|                 if (!data.Exists | ||||
|                     || data.Attributes.HasFlag(FileAttributes.Directory) | ||||
|                     || data.Attributes.HasFlag(FileAttributes.ReadOnly)) | ||||
|                 if (_updateTimer != null) | ||||
|                 { | ||||
|                     return false; | ||||
|                     _updateTimer.Dispose(); | ||||
|                     _updateTimer = null; | ||||
|                 } | ||||
|             } | ||||
|             catch (IOException) | ||||
|             { | ||||
|                 return false; | ||||
|             } | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 using (_fileSystem.GetFileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)) | ||||
|                 { | ||||
|                     //file is not locked | ||||
|                     return false; | ||||
|                 } | ||||
|             } | ||||
|             catch (DirectoryNotFoundException) | ||||
|             { | ||||
|                 return false; | ||||
|             } | ||||
|             catch (FileNotFoundException) | ||||
|             { | ||||
|                 return false; | ||||
|             } | ||||
|             catch (IOException) | ||||
|             { | ||||
|                 //the file is unavailable because it is: | ||||
|                 //still being written to | ||||
|                 //or being processed by another thread | ||||
|                 //or does not exist (has already been processed) | ||||
|                 Logger.Debug("{0} is locked.", path); | ||||
|                 return true; | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
| @ -599,14 +539,7 @@ namespace MediaBrowser.Server.Implementations.IO | ||||
|                 watcher.Dispose(); | ||||
|             } | ||||
| 
 | ||||
|             lock (_timerLock) | ||||
|             { | ||||
|                 if (_updateTimer != null) | ||||
|                 { | ||||
|                     _updateTimer.Dispose(); | ||||
|                     _updateTimer = null; | ||||
|                 } | ||||
|             } | ||||
|             DisposeTimer(); | ||||
| 
 | ||||
|             _fileSystemWatchers.Clear(); | ||||
|             _affectedPaths.Clear(); | ||||
| @ -137,7 +137,7 @@ namespace MediaBrowser.Server.Implementations.Library | ||||
| 
 | ||||
|         private IEnumerable<IMetadataSaver> _savers; | ||||
| 
 | ||||
|         private readonly Func<IDirectoryWatchers> _directoryWatchersFactory; | ||||
|         private readonly Func<ILibraryMonitor> _libraryMonitorFactory; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// The _library items cache | ||||
| @ -180,14 +180,14 @@ namespace MediaBrowser.Server.Implementations.Library | ||||
|         /// <param name="userManager">The user manager.</param> | ||||
|         /// <param name="configurationManager">The configuration manager.</param> | ||||
|         /// <param name="userDataRepository">The user data repository.</param> | ||||
|         public LibraryManager(ILogger logger, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager, IUserDataManager userDataRepository, Func<IDirectoryWatchers> directoryWatchersFactory, IFileSystem fileSystem) | ||||
|         public LibraryManager(ILogger logger, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager, IUserDataManager userDataRepository, Func<ILibraryMonitor> libraryMonitorFactory, IFileSystem fileSystem) | ||||
|         { | ||||
|             _logger = logger; | ||||
|             _taskManager = taskManager; | ||||
|             _userManager = userManager; | ||||
|             ConfigurationManager = configurationManager; | ||||
|             _userDataRepository = userDataRepository; | ||||
|             _directoryWatchersFactory = directoryWatchersFactory; | ||||
|             _libraryMonitorFactory = libraryMonitorFactory; | ||||
|             _fileSystem = fileSystem; | ||||
|             ByReferenceItems = new ConcurrentDictionary<Guid, BaseItem>(); | ||||
| 
 | ||||
| @ -934,7 +934,7 @@ namespace MediaBrowser.Server.Implementations.Library | ||||
|         /// <returns>Task.</returns> | ||||
|         public async Task ValidateMediaLibraryInternal(IProgress<double> progress, CancellationToken cancellationToken) | ||||
|         { | ||||
|             _directoryWatchersFactory().Stop(); | ||||
|             _libraryMonitorFactory().Stop(); | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
| @ -942,7 +942,7 @@ namespace MediaBrowser.Server.Implementations.Library | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 _directoryWatchersFactory().Start(); | ||||
|                 _libraryMonitorFactory().Start(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @ -1462,13 +1462,13 @@ namespace MediaBrowser.Server.Implementations.Library | ||||
| 
 | ||||
|                 var semaphore = _fileLocks.GetOrAdd(path, key => new SemaphoreSlim(1, 1)); | ||||
| 
 | ||||
|                 var directoryWatchers = _directoryWatchersFactory(); | ||||
|                 var directoryWatchers = _libraryMonitorFactory(); | ||||
| 
 | ||||
|                 await semaphore.WaitAsync().ConfigureAwait(false); | ||||
| 
 | ||||
|                 try | ||||
|                 { | ||||
|                     directoryWatchers.TemporarilyIgnore(path); | ||||
|                     directoryWatchers.ReportFileSystemChangeBeginning(path); | ||||
|                     saver.Save(item, CancellationToken.None); | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
| @ -1477,7 +1477,7 @@ namespace MediaBrowser.Server.Implementations.Library | ||||
|                 } | ||||
|                 finally | ||||
|                 { | ||||
|                     directoryWatchers.RemoveTempIgnore(path); | ||||
|                     directoryWatchers.ReportFileSystemChangeComplete(path, false); | ||||
|                     semaphore.Release(); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @ -137,7 +137,7 @@ | ||||
|     <Compile Include="HttpServer\StreamWriter.cs" /> | ||||
|     <Compile Include="HttpServer\SwaggerService.cs" /> | ||||
|     <Compile Include="Drawing\ImageProcessor.cs" /> | ||||
|     <Compile Include="IO\DirectoryWatchers.cs" /> | ||||
|     <Compile Include="IO\LibraryMonitor.cs" /> | ||||
|     <Compile Include="Library\CoreResolutionIgnoreRule.cs" /> | ||||
|     <Compile Include="Library\LibraryManager.cs" /> | ||||
|     <Compile Include="Library\SearchEngine.cs" /> | ||||
|  | ||||
| @ -137,7 +137,7 @@ namespace MediaBrowser.ServerApplication | ||||
|         /// Gets or sets the directory watchers. | ||||
|         /// </summary> | ||||
|         /// <value>The directory watchers.</value> | ||||
|         private IDirectoryWatchers DirectoryWatchers { get; set; } | ||||
|         private ILibraryMonitor LibraryMonitor { get; set; } | ||||
|         /// <summary> | ||||
|         /// Gets or sets the provider manager. | ||||
|         /// </summary> | ||||
| @ -273,13 +273,13 @@ namespace MediaBrowser.ServerApplication | ||||
|             UserManager = new UserManager(Logger, ServerConfigurationManager, UserRepository); | ||||
|             RegisterSingleInstance(UserManager); | ||||
| 
 | ||||
|             LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => DirectoryWatchers, FileSystemManager); | ||||
|             LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager); | ||||
|             RegisterSingleInstance(LibraryManager); | ||||
| 
 | ||||
|             DirectoryWatchers = new DirectoryWatchers(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager); | ||||
|             RegisterSingleInstance(DirectoryWatchers); | ||||
|             LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager); | ||||
|             RegisterSingleInstance(LibraryMonitor); | ||||
| 
 | ||||
|             ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, DirectoryWatchers, LogManager, FileSystemManager, ItemRepository); | ||||
|             ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ItemRepository); | ||||
|             RegisterSingleInstance(ProviderManager); | ||||
| 
 | ||||
|             RegisterSingleInstance<ISearchEngine>(() => new SearchEngine(LogManager, LibraryManager, UserManager)); | ||||
| @ -306,7 +306,7 @@ namespace MediaBrowser.ServerApplication | ||||
|             var newsService = new Server.Implementations.News.NewsService(ApplicationPaths, JsonSerializer); | ||||
|             RegisterSingleInstance<INewsService>(newsService); | ||||
| 
 | ||||
|             var fileOrganizationService = new FileOrganizationService(TaskManager, FileOrganizationRepository, Logger, DirectoryWatchers, LibraryManager, ServerConfigurationManager, FileSystemManager); | ||||
|             var fileOrganizationService = new FileOrganizationService(TaskManager, FileOrganizationRepository, Logger, LibraryMonitor, LibraryManager, ServerConfigurationManager, FileSystemManager); | ||||
|             RegisterSingleInstance<IFileOrganizationService>(fileOrganizationService); | ||||
| 
 | ||||
|             progress.Report(15); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user