roadie/Roadie.Api.Library/Processors/FolderProcessor.cs

140 lines
6.4 KiB
C#
Raw Normal View History

2018-11-11 21:13:19 +00:00
using Microsoft.Extensions.Logging;
using Roadie.Library.Caching;
2018-11-04 20:33:37 +00:00
using Roadie.Library.Configuration;
using Roadie.Library.Data;
using Roadie.Library.Encoding;
2018-12-15 22:35:20 +00:00
using Roadie.Library.Engines;
2018-11-03 21:21:36 +00:00
using Roadie.Library.Extensions;
2018-12-15 22:35:20 +00:00
using Roadie.Library.Factories;
2018-11-03 21:21:36 +00:00
using Roadie.Library.FilePlugins;
2018-12-15 22:57:51 +00:00
using Roadie.Library.MetaData.Audio;
using Roadie.Library.MetaData.ID3Tags;
2018-11-04 20:33:37 +00:00
using Roadie.Library.Utility;
2018-11-03 21:21:36 +00:00
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace Roadie.Library.Processors
{
public sealed class FolderProcessor : ProcessorBase
{
private readonly FileProcessor _fileProcessor;
2018-11-04 20:33:37 +00:00
public int? ProcessLimit { get; set; }
2018-11-03 21:21:36 +00:00
private FileProcessor FileProcessor
{
get
{
return this._fileProcessor;
}
}
2018-12-15 22:57:51 +00:00
public FolderProcessor(IRoadieSettings configuration, IHttpEncoder httpEncoder, string destinationRoot, IRoadieDbContext context, ICacheManager cacheManager, ILogger logger, IArtistLookupEngine artistLookupEngine, IArtistFactory artistFactory, IReleaseFactory releaseFactory, IImageFactory imageFactory, IReleaseLookupEngine releaseLookupEngine, IAudioMetaDataHelper audioMetaDataHelper)
: base(configuration, httpEncoder, destinationRoot, context, cacheManager, logger, artistLookupEngine, artistFactory, releaseFactory, imageFactory, releaseLookupEngine, audioMetaDataHelper)
2018-11-03 21:21:36 +00:00
{
SimpleContract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(destinationRoot), "Invalid Destination Folder");
2018-12-15 22:57:51 +00:00
this._fileProcessor = new FileProcessor(configuration, httpEncoder, destinationRoot, context, cacheManager, logger, artistLookupEngine, artistFactory, releaseFactory, imageFactory, releaseLookupEngine, audioMetaDataHelper);
2018-11-03 21:21:36 +00:00
}
2018-12-15 22:35:20 +00:00
public static OperationResult<bool> DeleteEmptyFolders(DirectoryInfo processingFolder, ILogger logger)
2018-11-04 20:33:37 +00:00
{
var result = new OperationResult<bool>();
try
{
result.IsSuccess = FolderPathHelper.DeleteEmptyFolders(processingFolder);
}
catch (Exception ex)
{
2018-12-15 22:35:20 +00:00
logger.LogError(ex, string.Format("Error Deleting Empty Folder [{0}] Error [{1}]", processingFolder.FullName, ex.Serialize()));
2018-11-04 20:33:37 +00:00
}
return result;
}
2018-12-14 23:38:48 +00:00
public async Task<OperationResult<bool>> Process(DirectoryInfo folder, bool doJustInfo, int? submissionId = null)
2018-11-03 21:21:36 +00:00
{
var sw = new Stopwatch();
sw.Start();
2018-12-14 23:38:48 +00:00
await this.PreProcessFolder(folder, doJustInfo);
2018-11-03 21:21:36 +00:00
int processedFiles = 0;
var pluginResultInfos = new List<PluginResultInfo>();
var errors = new List<string>();
2018-12-14 23:38:48 +00:00
2018-11-03 21:21:36 +00:00
this.FileProcessor.SubmissionId = submissionId;
2018-12-14 23:38:48 +00:00
foreach (var file in Directory.EnumerateFiles(folder.FullName, "*.*", SearchOption.AllDirectories).ToArray())
2018-11-03 21:21:36 +00:00
{
var operation = await this.FileProcessor.Process(file, doJustInfo);
2018-11-04 20:33:37 +00:00
if (operation != null && operation.AdditionalData != null && operation.AdditionalData.ContainsKey(PluginResultInfo.AdditionalDataKeyPluginResultInfo))
2018-11-03 21:21:36 +00:00
{
pluginResultInfos.Add(operation.AdditionalData[PluginResultInfo.AdditionalDataKeyPluginResultInfo] as PluginResultInfo);
}
2018-11-04 20:33:37 +00:00
if (operation == null)
2018-11-03 21:21:36 +00:00
{
2018-12-14 23:38:48 +00:00
var fileExtensionsToDelete = this.Configuration.FileExtensionsToDelete ?? new string[0];
2018-11-03 21:21:36 +00:00
if (fileExtensionsToDelete.Any(x => x.Equals(Path.GetExtension(file), StringComparison.OrdinalIgnoreCase)))
{
if (!doJustInfo)
{
if (!Path.GetFileNameWithoutExtension(file).ToLower().Equals("cover"))
{
File.Delete(file);
2018-11-11 21:13:19 +00:00
this.Logger.LogInformation("x Deleted File [{0}], Was foud in in FileExtensionsToDelete", file);
2018-11-03 21:21:36 +00:00
}
}
}
}
processedFiles++;
if (this.ProcessLimit.HasValue && processedFiles > this.ProcessLimit.Value)
{
break;
}
}
2018-12-14 23:38:48 +00:00
await this.PostProcessFolder(folder, pluginResultInfos, doJustInfo);
2018-11-03 21:21:36 +00:00
sw.Stop();
2018-12-14 23:38:48 +00:00
this.Logger.LogInformation("** Completed! Processed Folder [{0}]: Processed Files [{1}] : Elapsed Time [{2}]", folder.FullName.ToString(), processedFiles, sw.Elapsed);
2018-11-03 21:21:36 +00:00
return new OperationResult<bool>
{
IsSuccess = !errors.Any(),
AdditionalData = new Dictionary<string, object> {
{ "processedFiles", processedFiles },
2018-12-15 23:22:02 +00:00
{ "newArtists", this.ArtistLookupEngine.AddedArtistIds.Count() },
{ "newReleases", this.ReleaseLookupEngine.AddedReleaseIds.Count() },
2018-12-16 23:37:19 +00:00
{ "newTracks", this.ReleaseFactory.AddedTrackIds.Count() }
2018-11-03 21:21:36 +00:00
},
OperationTime = sw.ElapsedMilliseconds
};
}
/// <summary>
/// Perform any operations to the given folder and the plugin results after processing
/// </summary>
private async Task<bool> PostProcessFolder(DirectoryInfo inboundFolder, IEnumerable<PluginResultInfo> pluginResults, bool doJustInfo)
{
SimpleContract.Requires<ArgumentNullException>(inboundFolder != null, "Invalid InboundFolder");
if (!doJustInfo)
{
2018-12-15 22:35:20 +00:00
FolderProcessor.DeleteEmptyFolders(inboundFolder, this.Logger);
2018-11-03 21:21:36 +00:00
}
if (pluginResults != null)
{
foreach (var releasesInfo in pluginResults.GroupBy(x => x.ReleaseId).Select(x => x.First()))
{
await this.ReleaseFactory.ScanReleaseFolder(releasesInfo.ReleaseId, this.DestinationRoot, doJustInfo);
}
}
return true;
}
2018-11-04 20:33:37 +00:00
/// <summary>
/// Perform any operations to the given folder before processing
/// </summary>
2018-12-24 19:40:49 +00:00
private Task<bool> PreProcessFolder(DirectoryInfo inboundFolder, bool doJustInfo = false)
2018-11-03 21:21:36 +00:00
{
2018-12-24 19:40:49 +00:00
return Task.FromResult(true);
2018-11-03 21:21:36 +00:00
}
}
2018-11-04 20:33:37 +00:00
}