aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs')
-rw-r--r--MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs100
1 files changed, 94 insertions, 6 deletions
diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs
index 9e16613e6..a42eba6ca 100644
--- a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs
+++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs
@@ -3,16 +3,21 @@ using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.FileOrganization;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.FileOrganization;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Querying;
using System;
+using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Controller.Session;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Common.Events;
namespace MediaBrowser.Server.Implementations.FileOrganization
{
@@ -26,6 +31,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
private readonly IServerConfigurationManager _config;
private readonly IFileSystem _fileSystem;
private readonly IProviderManager _providerManager;
+ private readonly ConcurrentDictionary<string, bool> _inProgressItemIds = new ConcurrentDictionary<string, bool>();
+
+ public event EventHandler<GenericEventArgs<FileOrganizationResult>> ItemAdded;
+ public event EventHandler<GenericEventArgs<FileOrganizationResult>> ItemUpdated;
+ public event EventHandler<GenericEventArgs<FileOrganizationResult>> ItemRemoved;
+ public event EventHandler LogReset;
public FileOrganizationService(ITaskManager taskManager, IFileOrganizationRepository repo, ILogger logger, ILibraryMonitor libraryMonitor, ILibraryManager libraryManager, IServerConfigurationManager config, IFileSystem fileSystem, IProviderManager providerManager)
{
@@ -58,12 +69,26 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
public QueryResult<FileOrganizationResult> GetResults(FileOrganizationResultQuery query)
{
- return _repo.GetResults(query);
+ var results = _repo.GetResults(query);
+
+ foreach (var result in results.Items)
+ {
+ result.IsInProgress = _inProgressItemIds.ContainsKey(result.Id);
+ }
+
+ return results;
}
public FileOrganizationResult GetResult(string id)
{
- return _repo.GetResult(id);
+ var result = _repo.GetResult(id);
+
+ if (result != null)
+ {
+ result.IsInProgress = _inProgressItemIds.ContainsKey(result.Id);
+ }
+
+ return result;
}
public FileOrganizationResult GetResultBySourcePath(string path)
@@ -78,11 +103,17 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
return GetResult(id);
}
- public Task DeleteOriginalFile(string resultId)
+ public async Task DeleteOriginalFile(string resultId)
{
var result = _repo.GetResult(resultId);
_logger.Info("Requested to delete {0}", result.OriginalPath);
+
+ if (!AddToInProgressList(result, false))
+ {
+ throw new Exception("Path is currently processed otherwise. Please try again later.");
+ }
+
try
{
_fileSystem.DeleteFile(result.OriginalPath);
@@ -91,8 +122,14 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
{
_logger.ErrorException("Error deleting {0}", ex, result.OriginalPath);
}
+ finally
+ {
+ RemoveFromInprogressList(result);
+ }
- return _repo.Delete(resultId);
+ await _repo.Delete(resultId);
+
+ EventHelper.FireEventIfNotNull(ItemRemoved, this, new GenericEventArgs<FileOrganizationResult>(result), _logger);
}
private AutoOrganizeOptions GetAutoOrganizeOptions()
@@ -121,9 +158,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
}
}
- public Task ClearLog()
+ public async Task ClearLog()
{
- return _repo.DeleteAll();
+ await _repo.DeleteAll();
+ EventHelper.FireEventIfNotNull(LogReset, this, EventArgs.Empty, _logger);
}
public async Task PerformEpisodeOrganization(EpisodeFileOrganizationRequest request)
@@ -189,5 +227,55 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
_config.SaveAutoOrganizeOptions(options);
}
}
+
+ /// <summary>
+ /// Attempts to add a an item to the list of currently processed items.
+ /// </summary>
+ /// <param name="result">The result item.</param>
+ /// <param name="isNewItem">Passing true will notify the client to reload all items, otherwise only a single item will be refreshed.</param>
+ /// <returns>True if the item was added, False if the item is already contained in the list.</returns>
+ public bool AddToInProgressList(FileOrganizationResult result, bool isNewItem)
+ {
+ if (string.IsNullOrWhiteSpace(result.Id))
+ {
+ result.Id = result.OriginalPath.GetMD5().ToString("N");
+ }
+
+ if (!_inProgressItemIds.TryAdd(result.Id, false))
+ {
+ return false;
+ }
+
+ result.IsInProgress = true;
+
+ if (isNewItem)
+ {
+ EventHelper.FireEventIfNotNull(ItemAdded, this, new GenericEventArgs<FileOrganizationResult>(result), _logger);
+ }
+ else
+ {
+ EventHelper.FireEventIfNotNull(ItemUpdated, this, new GenericEventArgs<FileOrganizationResult>(result), _logger);
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// Removes an item from the list of currently processed items.
+ /// </summary>
+ /// <param name="result">The result item.</param>
+ /// <returns>True if the item was removed, False if the item was not contained in the list.</returns>
+ public bool RemoveFromInprogressList(FileOrganizationResult result)
+ {
+ bool itemValue;
+ var retval = _inProgressItemIds.TryRemove(result.Id, out itemValue);
+
+ result.IsInProgress = false;
+
+ EventHelper.FireEventIfNotNull(ItemUpdated, this, new GenericEventArgs<FileOrganizationResult>(result), _logger);
+
+ return retval;
+ }
+
}
}