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

169 lines
7.2 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-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 FileProcessor : ProcessorBase
{
private IEnumerable<IFilePlugin> _plugins = null;
public IEnumerable<IFilePlugin> Plugins
{
get
{
2018-11-04 20:33:37 +00:00
if (this._plugins == null)
2018-11-03 21:21:36 +00:00
{
var plugins = new List<IFilePlugin>();
try
{
var type = typeof(IFilePlugin);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
foreach (Type t in types)
{
if (t.GetInterface("IFilePlugin") != null && !t.IsAbstract && !t.IsInterface)
{
2018-12-15 22:57:51 +00:00
IFilePlugin plugin = Activator.CreateInstance(t, new object[] { this.Configuration, this.HttpEncoder, this.ArtistFactory, this.ReleaseFactory,
this.ImageFactory, this.CacheManager, this.Logger, this.ArtistLookupEngine,
this.ReleaseLookupEngine, this.AudioMetaDataHelper}) as IFilePlugin;
2018-11-03 21:21:36 +00:00
plugins.Add(plugin);
}
}
}
2018-12-14 23:38:48 +00:00
catch (Exception ex)
2018-11-04 20:33:37 +00:00
{
2018-12-14 23:38:48 +00:00
this.Logger.LogError(ex);
2018-11-03 21:21:36 +00:00
}
this._plugins = plugins.ToArray();
}
return this._plugins;
}
}
2018-12-15 22:57:51 +00:00
public FileProcessor(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
{
}
2018-11-04 20:33:37 +00:00
public static string DetermineFileType(System.IO.FileInfo fileinfo)
{
string r = MimeMapping.MimeUtility.GetMimeMapping(fileinfo.FullName);
if (r.Equals("application/octet-stream"))
{
if (fileinfo.Extension.Equals(".cue"))
{
r = "audio/r-cue";
}
if (fileinfo.Extension.Equals(".mp4") || fileinfo.Extension.Equals(".m4a"))
{
r = "audio/mp4";
}
}
Trace.WriteLine(string.Format("FileType [{0}] For File [{1}]", r, fileinfo.FullName));
return r;
}
2018-11-03 21:21:36 +00:00
public async Task<OperationResult<bool>> Process(string filename, bool doJustInfo = false)
{
return await this.Process(new FileInfo(filename), doJustInfo);
}
public async Task<OperationResult<bool>> Process(FileInfo fileInfo, bool doJustInfo = false)
{
var result = new OperationResult<bool>();
try
{
2018-11-04 20:33:37 +00:00
// Determine what type of file this is
2018-11-03 21:21:36 +00:00
var fileType = FileProcessor.DetermineFileType(fileInfo);
OperationResult<bool> pluginResult = null;
foreach (var p in this.Plugins)
{
// See if there is a plugin
if (p.HandlesTypes.Contains(fileType))
{
pluginResult = await p.Process(this.DestinationRoot, fileInfo, doJustInfo, this.SubmissionId);
break;
}
}
if (!doJustInfo)
{
// If no plugin, or if plugin not successfull and toggle then move unknown file
if ((pluginResult == null || !pluginResult.IsSuccess) && this.DoMoveUnknowns)
{
var uf = this.UnknownFolder;
if (!string.IsNullOrEmpty(uf))
{
if (!Directory.Exists(uf))
{
Directory.CreateDirectory(uf);
}
if (!fileInfo.DirectoryName.Equals(this.UnknownFolder))
{
if (File.Exists(fileInfo.FullName))
{
var df = Path.Combine(this.UnknownFolder, string.Format("{0}~{1}~{2}", Guid.NewGuid(), fileInfo.Directory.Name, fileInfo.Name));
2018-11-11 21:13:19 +00:00
this.Logger.LogDebug("Moving Unknown/Invalid File [{0}] -> [{1}] to UnknownFolder", fileInfo.FullName, df);
2018-11-03 21:21:36 +00:00
fileInfo.MoveTo(df);
}
}
}
}
}
result = pluginResult;
}
catch (System.IO.PathTooLongException ex)
{
2018-11-11 21:13:19 +00:00
this.Logger.LogError(ex, string.Format("Error Processing File. File Name Too Long. Deleting."));
2018-11-03 21:21:36 +00:00
if (!doJustInfo)
{
fileInfo.Delete();
}
}
catch (Exception ex)
{
var willMove = !fileInfo.DirectoryName.Equals(this.UnknownFolder);
2018-11-11 21:13:19 +00:00
this.Logger.LogError(ex, string.Format("Error Processing File [{0}], WillMove [{1}]\n{2}", fileInfo.FullName, willMove, ex.Serialize()));
2018-11-03 21:21:36 +00:00
string newPath = null;
try
{
newPath = Path.Combine(this.UnknownFolder, fileInfo.Directory.Parent.Name, fileInfo.Directory.Name, fileInfo.Name);
if (willMove && !doJustInfo)
{
var directoryPath = Path.GetDirectoryName(newPath);
2018-11-04 20:33:37 +00:00
if (!Directory.Exists(directoryPath))
2018-11-03 21:21:36 +00:00
{
Directory.CreateDirectory(directoryPath);
}
fileInfo.MoveTo(newPath);
}
}
catch (Exception ex1)
{
2018-11-11 21:13:19 +00:00
this.Logger.LogError(ex1, string.Format("Unable to move file [{0}] to [{1}]", fileInfo.FullName, newPath));
2018-11-03 21:21:36 +00:00
}
}
return result;
}
}
2018-11-04 20:33:37 +00:00
}