using MediaBrowser.Common.IO; using MediaBrowser.Common.Kernel; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Logging; using System; using System.IO; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Controller.IO { /// /// This class will manage our file system watching and modifications. Any process that needs to /// modify the directories that the system is watching for changes should use the methods of /// this class to do so. This way we can have the watchers correctly respond to only external changes. /// public class FileSystemManager : BaseManager { /// /// Gets or sets the directory watchers. /// /// The directory watchers. private DirectoryWatchers DirectoryWatchers { get; set; } /// /// The _logger /// private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// The kernel. /// The logger. /// The task manager. public FileSystemManager(Kernel kernel, ILogger logger, ITaskManager taskManager) : base(kernel) { _logger = logger; DirectoryWatchers = new DirectoryWatchers(logger, taskManager); } /// /// Start the directory watchers on our library folders /// public void StartWatchers() { DirectoryWatchers.Start(); } /// /// Saves to library filesystem. /// /// The item. /// The path. /// The data to save. /// The cancellation token. /// Task. /// public async Task SaveToLibraryFilesystem(BaseItem item, string path, Stream dataToSave, CancellationToken cancellationToken) { if (item == null) { throw new ArgumentNullException(); } if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(); } if (dataToSave == null) { throw new ArgumentNullException(); } if (cancellationToken == null) { throw new ArgumentNullException(); } cancellationToken.ThrowIfCancellationRequested(); //Tell the watchers to ignore DirectoryWatchers.TemporarilyIgnore(path); //Make the mod dataToSave.Position = 0; try { using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous)) { await dataToSave.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, cancellationToken).ConfigureAwait(false); dataToSave.Dispose(); // If this is ever used for something other than metadata we can add a file type param item.ResolveArgs.AddMetadataFile(path); } } finally { //Remove the ignore DirectoryWatchers.RemoveTempIgnore(path); } } /// /// Releases unmanaged and - optionally - managed resources. /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected override void Dispose(bool dispose) { if (dispose) { DirectoryWatchers.Dispose(); } base.Dispose(dispose); } } }