aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations/IO
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2016-11-04 14:56:47 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2016-11-04 14:56:47 -0400
commit72aaecb27930e04aa356febf35db2372bc417166 (patch)
treec72bb0ed40bd257b93d4b11f315bbbe24e23920d /MediaBrowser.Server.Implementations/IO
parenta7b11c8ee952ca43fe949ab4f1b6577e94ce6bba (diff)
move classes to new server project
Diffstat (limited to 'MediaBrowser.Server.Implementations/IO')
-rw-r--r--MediaBrowser.Server.Implementations/IO/FileRefresher.cs323
-rw-r--r--MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs14
2 files changed, 5 insertions, 332 deletions
diff --git a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs
deleted file mode 100644
index 2742e1a26..000000000
--- a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs
+++ /dev/null
@@ -1,323 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Common.Events;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Extensions;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Tasks;
-using MediaBrowser.Model.Threading;
-
-namespace MediaBrowser.Server.Implementations.IO
-{
- public class FileRefresher : IDisposable
- {
- private ILogger Logger { get; set; }
- private ITaskManager TaskManager { get; set; }
- private ILibraryManager LibraryManager { get; set; }
- private IServerConfigurationManager ConfigurationManager { get; set; }
- private readonly IFileSystem _fileSystem;
- private readonly List<string> _affectedPaths = new List<string>();
- private ITimer _timer;
- private readonly ITimerFactory _timerFactory;
- private readonly object _timerLock = new object();
- public string Path { get; private set; }
-
- public event EventHandler<EventArgs> Completed;
-
- public FileRefresher(string path, IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, ITaskManager taskManager, ILogger logger, ITimerFactory timerFactory)
- {
- logger.Debug("New file refresher created for {0}", path);
- Path = path;
-
- _fileSystem = fileSystem;
- ConfigurationManager = configurationManager;
- LibraryManager = libraryManager;
- TaskManager = taskManager;
- Logger = logger;
- _timerFactory = timerFactory;
- AddPath(path);
- }
-
- private void AddAffectedPath(string path)
- {
- if (string.IsNullOrWhiteSpace(path))
- {
- throw new ArgumentNullException("path");
- }
-
- if (!_affectedPaths.Contains(path, StringComparer.Ordinal))
- {
- _affectedPaths.Add(path);
- }
- }
-
- public void AddPath(string path)
- {
- if (string.IsNullOrWhiteSpace(path))
- {
- throw new ArgumentNullException("path");
- }
-
- lock (_timerLock)
- {
- AddAffectedPath(path);
- }
- RestartTimer();
- }
-
- public void RestartTimer()
- {
- if (_disposed)
- {
- return;
- }
-
- lock (_timerLock)
- {
- if (_disposed)
- {
- return;
- }
-
- if (_timer == null)
- {
- _timer = _timerFactory.Create(OnTimerCallback, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1));
- }
- else
- {
- _timer.Change(TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1));
- }
- }
- }
-
- public void ResetPath(string path, string affectedFile)
- {
- lock (_timerLock)
- {
- Logger.Debug("Resetting file refresher from {0} to {1}", Path, path);
-
- Path = path;
- AddAffectedPath(path);
-
- if (!string.IsNullOrWhiteSpace(affectedFile))
- {
- AddAffectedPath(affectedFile);
- }
- }
- RestartTimer();
- }
-
- private async void OnTimerCallback(object state)
- {
- List<string> paths;
-
- lock (_timerLock)
- {
- paths = _affectedPaths.ToList();
- }
-
- // Extend the timer as long as any of the paths are still being written to.
- if (paths.Any(IsFileLocked))
- {
- Logger.Info("Timer extended.");
- RestartTimer();
- return;
- }
-
- Logger.Debug("Timer stopped.");
-
- DisposeTimer();
- EventHelper.FireEventIfNotNull(Completed, this, EventArgs.Empty, Logger);
-
- try
- {
- await ProcessPathChanges(paths.ToList()).ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error processing directory changes", ex);
- }
- }
-
- private async Task ProcessPathChanges(List<string> paths)
- {
- var itemsToRefresh = paths
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .Select(GetAffectedBaseItem)
- .Where(item => item != null)
- .DistinctBy(i => i.Id)
- .ToList();
-
- foreach (var p in paths)
- {
- Logger.Info(p + " reports change.");
- }
-
- // If the root folder changed, run the library task so the user can see it
- if (itemsToRefresh.Any(i => i is AggregateFolder))
- {
- LibraryManager.ValidateMediaLibrary(new Progress<double>(), CancellationToken.None);
- return;
- }
-
- foreach (var item in itemsToRefresh)
- {
- Logger.Info(item.Name + " (" + item.Path + ") will be refreshed.");
-
- try
- {
- await item.ChangedExternally().ConfigureAwait(false);
- }
- catch (IOException ex)
- {
- // For now swallow and log.
- // Research item: If an IOException occurs, the item may be in a disconnected state (media unavailable)
- // Should we remove it from it's parent?
- Logger.ErrorException("Error refreshing {0}", ex, item.Name);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error refreshing {0}", ex, item.Name);
- }
- }
- }
-
- /// <summary>
- /// Gets the affected base item.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns>BaseItem.</returns>
- private BaseItem GetAffectedBaseItem(string path)
- {
- BaseItem item = null;
-
- while (item == null && !string.IsNullOrEmpty(path))
- {
- item = LibraryManager.FindByPath(path, null);
-
- path = System.IO.Path.GetDirectoryName(path);
- }
-
- if (item != null)
- {
- // If the item has been deleted find the first valid parent that still exists
- while (!_fileSystem.DirectoryExists(item.Path) && !_fileSystem.FileExists(item.Path))
- {
- item = item.GetParent();
-
- if (item == null)
- {
- break;
- }
- }
- }
-
- return item;
- }
-
- private bool IsFileLocked(string path)
- {
- if (Environment.OSVersion.Platform != PlatformID.Win32NT)
- {
- // Causing lockups on linux
- return false;
- }
-
- try
- {
- var data = _fileSystem.GetFileSystemInfo(path);
-
- if (!data.Exists
- || data.IsDirectory
-
- // Opening a writable stream will fail with readonly files
- || data.IsReadOnly)
- {
- return false;
- }
- }
- catch (IOException)
- {
- return false;
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error getting file system info for: {0}", ex, path);
- return false;
- }
-
- // In order to determine if the file is being written to, we have to request write access
- // But if the server only has readonly access, this is going to cause this entire algorithm to fail
- // So we'll take a best guess about our access level
- var requestedFileAccess = ConfigurationManager.Configuration.SaveLocalMeta
- ? FileAccessMode.ReadWrite
- : FileAccessMode.Read;
-
- try
- {
- using (_fileSystem.GetFileStream(path, FileOpenMode.Open, requestedFileAccess, FileShareMode.ReadWrite))
- {
- //file is not locked
- return false;
- }
- }
- //catch (DirectoryNotFoundException)
- //{
- // // File may have been deleted
- // return false;
- //}
- catch (FileNotFoundException)
- {
- // File may have been deleted
- return false;
- }
- catch (UnauthorizedAccessException)
- {
- Logger.Debug("No write permission for: {0}.", path);
- 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 (Exception ex)
- {
- Logger.ErrorException("Error determining if file is locked: {0}", ex, path);
- return false;
- }
- }
-
- private void DisposeTimer()
- {
- lock (_timerLock)
- {
- if (_timer != null)
- {
- _timer.Dispose();
- _timer = null;
- }
- }
- }
-
- private bool _disposed;
- public void Dispose()
- {
- _disposed = true;
- DisposeTimer();
- }
- }
-}
diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
index 49cb1e75f..34fc85e7b 100644
--- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
+++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
@@ -10,13 +10,14 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
+using Emby.Server.Implementations.IO;
using MediaBrowser.Common.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Controller;
using MediaBrowser.Controller.IO;
+using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Threading;
-using Microsoft.Win32;
namespace MediaBrowser.Server.Implementations.IO
{
@@ -142,7 +143,7 @@ namespace MediaBrowser.Server.Implementations.IO
/// <summary>
/// Initializes a new instance of the <see cref="LibraryMonitor" /> class.
/// </summary>
- public LibraryMonitor(ILogManager logManager, ITaskManager taskManager, ILibraryManager libraryManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ITimerFactory timerFactory)
+ public LibraryMonitor(ILogManager logManager, ITaskManager taskManager, ILibraryManager libraryManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ITimerFactory timerFactory, ISystemEvents systemEvents)
{
if (taskManager == null)
{
@@ -156,15 +157,10 @@ namespace MediaBrowser.Server.Implementations.IO
_fileSystem = fileSystem;
_timerFactory = timerFactory;
- SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
+ systemEvents.Resume += _systemEvents_Resume;
}
- /// <summary>
- /// Handles the PowerModeChanged event of the SystemEvents control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="PowerModeChangedEventArgs"/> instance containing the event data.</param>
- void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
+ private void _systemEvents_Resume(object sender, EventArgs e)
{
Restart();
}