diff --git a/Inspector/Program.cs b/Inspector/Program.cs index 422af43..9e955a9 100644 --- a/Inspector/Program.cs +++ b/Inspector/Program.cs @@ -24,6 +24,9 @@ public class Program [Required] public string Folder { get; } + [Option("-g", "Only generate Roadie data files", CommandOptionType.NoValue)] + public bool OnlyCreateRoadieFiles { get; } + [Option("-r", "Only show what would be done, don't modify any files", CommandOptionType.NoValue)] public bool IsReadOnly { get; } @@ -44,7 +47,14 @@ private void OnExecute() var host = builder.Build(); var inspector = new Roadie.Library.Inspect.Inspector(host.Services.GetRequiredService()); - inspector.Inspect(DoCopy, IsReadOnly, Folder, Destination ?? Folder, DontAppendSubFolder, IsReadOnly ? true : DontDeleteEmptyFolders, DontRunPreScript); + if (OnlyCreateRoadieFiles) + { + inspector.GenerateRoadieDataFiles(Folder); + } + else + { + inspector.Inspect(DoCopy, IsReadOnly, Folder, Destination ?? Folder, DontAppendSubFolder, IsReadOnly ? true : DontDeleteEmptyFolders, DontRunPreScript); + } } } } \ No newline at end of file diff --git a/Inspector/Properties/launchSettings.json b/Inspector/Properties/launchSettings.json index 619a9ac..a085978 100644 --- a/Inspector/Properties/launchSettings.json +++ b/Inspector/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Inspector": { "commandName": "Project", - "commandLineArgs": "-f \"G:\\complete\\_\" -d \"M:\\inbound\"" + "commandLineArgs": "-g -f \"G:\\complete\\_\"" } } } \ No newline at end of file diff --git a/Roadie.Api.Library.Tests/ExtensionTests.cs b/Roadie.Api.Library.Tests/ExtensionTests.cs index 790d251..e0f0001 100644 --- a/Roadie.Api.Library.Tests/ExtensionTests.cs +++ b/Roadie.Api.Library.Tests/ExtensionTests.cs @@ -20,7 +20,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A1", Text = "A1" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R1", Text = "R1" } } @@ -32,7 +32,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A2", Text = "A2" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R4", Text = "R4" } } @@ -44,7 +44,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A1", Text = "A1" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R5", Text = "R5" } } @@ -56,7 +56,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A1", Text = "A1" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R1", Text = "R1" } } @@ -68,7 +68,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A3", Text = "A3" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R6", Text = "R6" } } @@ -80,7 +80,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A2", Text = "A2" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R5", Text = "R5" } } @@ -92,7 +92,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A2", Text = "A2" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R5", Text = "R5" } } @@ -104,7 +104,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A2", Text = "A2" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R5", Text = "R5" } } @@ -116,7 +116,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A2", Text = "A2" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R6", Text = "R6" } } @@ -128,7 +128,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A4", Text = "A4" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R7", Text = "R7" } } @@ -140,7 +140,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A5", Text = "A5" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R8", Text = "R8" } } @@ -152,7 +152,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A6", Text = "A6" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R9", Text = "R9" } } @@ -164,7 +164,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A7", Text = "A7" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R10", Text = "R10" } } @@ -176,7 +176,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A8", Text = "A8" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R11", Text = "R11" } } @@ -188,7 +188,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A9", Text = "A9" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R12", Text = "R12" } } @@ -200,7 +200,7 @@ public void ShuffleUniqueOrder() { Artist = new Models.DataToken { Value = "A10", Text = "A10" } }, - Release = new Models.Releases.ReleaseList + Release = new Models.Releases.ReleaseList { Release = new Models.DataToken { Value = "R13", Text = "R13" } } diff --git a/Roadie.Api.Library.Tests/LastFmHelperTests.cs b/Roadie.Api.Library.Tests/LastFmHelperTests.cs index d1e084c..66a3c58 100644 --- a/Roadie.Api.Library.Tests/LastFmHelperTests.cs +++ b/Roadie.Api.Library.Tests/LastFmHelperTests.cs @@ -61,7 +61,7 @@ public async Task LastFMReleaseSearch() var logger = new EventMessageLogger(); logger.Messages += MessageLogger_Messages; - var lfmHelper = new LastFmHelper(Configuration, CacheManager, new EventMessageLogger(), RoadieDbContext, HttpEncoder, _httpClientFactory); + var lfmHelper = new LastFmHelper(Configuration, CacheManager, new EventMessageLogger(), HttpEncoder, _httpClientFactory); var artistName = "Billy Joel"; var title = "Piano Man"; @@ -103,7 +103,7 @@ public async Task LastFMArtistSearch() } var logger = new EventMessageLogger(); logger.Messages += MessageLogger_Messages; - var lfmHelper = new LastFmHelper(Configuration, CacheManager, new EventMessageLogger(), RoadieDbContext, HttpEncoder, _httpClientFactory); + var lfmHelper = new LastFmHelper(Configuration, CacheManager, new EventMessageLogger(), HttpEncoder, _httpClientFactory); var artistName = "Billy Joel"; var sw = Stopwatch.StartNew(); diff --git a/Roadie.Api.Library/Caching/NewtonsoftCacheSerializer.cs b/Roadie.Api.Library/Caching/NewtonsoftCacheSerializer.cs index 9831cb7..6ee204f 100644 --- a/Roadie.Api.Library/Caching/NewtonsoftCacheSerializer.cs +++ b/Roadie.Api.Library/Caching/NewtonsoftCacheSerializer.cs @@ -17,7 +17,8 @@ public NewtonsoftCacheSerializer(ILogger logger) { ContractResolver = new IgnoreJsonAttributesResolver(), ReferenceLoopHandling = ReferenceLoopHandling.Ignore, - Formatting = Formatting.Indented + Formatting = Formatting.Indented, + NullValueHandling = NullValueHandling.Ignore }; } diff --git a/Roadie.Api.Library/Configuration/Inspector.cs b/Roadie.Api.Library/Configuration/Inspector.cs index 4a7a511..fd42f2f 100644 --- a/Roadie.Api.Library/Configuration/Inspector.cs +++ b/Roadie.Api.Library/Configuration/Inspector.cs @@ -3,13 +3,13 @@ public class Inspector : IInspector { /// - /// When true then make a copy of files to new destination versus moving files to destination. + /// When true then make a copy of files to new destination versus moving files to destination. /// public bool DoCopyFiles { get; set; } /// - /// When true then don't modify any files only report what would be done. + /// When true then don't modify any files only report what would be done. /// public bool IsInReadOnlyMode { get; set; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Engines/ArtistLookupEngine.cs b/Roadie.Api.Library/Engines/ArtistLookupEngine.cs index 38e79f9..f809504 100644 --- a/Roadie.Api.Library/Engines/ArtistLookupEngine.cs +++ b/Roadie.Api.Library/Engines/ArtistLookupEngine.cs @@ -245,7 +245,7 @@ public async Task> GetByName(AudioMetaData metaData, boo }; } - // See if roadie.json file exists in the metadata files folder, if so then use artist data from that + // See if roadie.artist.json file exists in the metadata files folder, if so then use artist data from that string releaseRoadieDataFilename = null; try { diff --git a/Roadie.Api.Library/Inspect/Inspector.cs b/Roadie.Api.Library/Inspect/Inspector.cs index a592244..1a11dd8 100644 --- a/Roadie.Api.Library/Inspect/Inspector.cs +++ b/Roadie.Api.Library/Inspect/Inspector.cs @@ -21,7 +21,6 @@ using System.Linq; using System.Management.Automation; using System.Net.Http; -using System.Text.Json; namespace Roadie.Library.Inspect { @@ -30,8 +29,11 @@ public class Inspector private const string Salt = "6856F2EE-5965-4345-884B-2CCA457AAF59"; private IRoadieSettings Configuration { get; } + private ILogger Logger => MessageLogger as ILogger; + private IEventMessageLogger MessageLogger { get; } + private ID3TagsHelper TagsHelper { get; } private IEnumerable _directoryPlugins; @@ -139,6 +141,7 @@ public Inspector(IHttpClientFactory httpClientFactory) var tagHelperLooper = new EventMessageLogger(); tagHelperLooper.Messages += MessageLogger_Messages; TagsHelper = new ID3TagsHelper(Configuration, CacheManager, tagHelperLooper, httpClientFactory); + } private void InspectImage(bool isReadOnly, bool doCopy, string dest, string subdirectory, FileInfo image) @@ -238,11 +241,11 @@ private string RunScript(string scriptFilename, bool doCopy, bool isReadOnly, st { if (!File.Exists(scriptFilename)) { - Console.WriteLine($"Script Not Found: [{ scriptFilename }]"); + Console.WriteLine($"Script Not Found: [{scriptFilename}]"); return null; } - Console.WriteLine($"Running Script: [{ scriptFilename }]"); + Console.WriteLine($"Running Script: [{scriptFilename}]"); var script = File.ReadAllText(scriptFilename); using (var ps = PowerShell.Create()) { @@ -269,17 +272,8 @@ private string RunScript(string scriptFilename, bool doCopy, bool isReadOnly, st public static string ArtistInspectorToken(AudioMetaData metaData) => ToToken(metaData.Artist); - public void Inspect(bool doCopy, bool isReadOnly, string directoryToInspect, string destination, bool dontAppendSubFolder, bool dontDeleteEmptyFolders, bool dontRunPreScripts) + void PrintInspectorBanner(string directory) { - Configuration.Inspector.IsInReadOnlyMode = isReadOnly; - Configuration.Inspector.DoCopyFiles = doCopy; - - var artistsFound = new List(); - var releasesFound = new List(); - var mp3FilesFoundCount = 0; - - Trace.Listeners.Add(new LoggingTraceListener()); - Console.ForegroundColor = ConsoleColor.Blue; Console.WriteLine(""); Console.WriteLine(" ▄▄▄ ▄▄▄· ·▄▄▄▄ ▪ ▄▄▄ . • ▌ ▄ ·. ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄· ▪ ▐ ▄ .▄▄ · ▄▄▄·▄▄▄ . ▄▄· ▄▄▄▄▄ ▄▄▄ "); @@ -295,14 +289,62 @@ public void Inspect(bool doCopy, bool isReadOnly, string directoryToInspect, str Console.WriteLine($"✨ Inspector Start, UTC [{DateTime.UtcNow.ToString("s")}]"); Console.ResetColor(); - if (!Directory.Exists(directoryToInspect)) + if (!Directory.Exists(directory)) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($"📛 Folder [{directory}] is not found."); + Console.ResetColor(); + return; + } + } + + public void GenerateRoadieDataFiles(string directory) + { + PrintInspectorBanner(directory); + + var roadieDataFilePlugin = DirectoryPlugins.FirstOrDefault(x => x.Description == RoadieDataFileCreator.RoadieDataFileCreatorDescription); + if(roadieDataFilePlugin == null) { Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine($"📛 Folder To Inspect [{ directoryToInspect }] is not found."); + Console.WriteLine($"📛 Unable to find Roadie Data File Creator Plugin."); Console.ResetColor(); return; } + Console.WriteLine($"╠╬═ Running Directory Plugin: {roadieDataFilePlugin.Description}"); + + // Get all the top level directorys in the directory + var directoryDirectories = Directory.GetDirectories(directory, "*.*", SearchOption.TopDirectoryOnly); + foreach(var directoryDirectory in directoryDirectories) + { + var directoryInfo = new DirectoryInfo(directoryDirectory); + + var pluginResult = roadieDataFilePlugin.Process(directoryInfo); + if (!pluginResult.IsSuccess) + { + Console.WriteLine($"📛 Plugin Failed: Error [{CacheManager.CacheSerializer.Serialize(pluginResult)}]"); + return; + } + if (!string.IsNullOrEmpty(pluginResult.Data)) + { + Console.WriteLine($"╠╣ Directory Plugin Message: {pluginResult.Data}"); + } + } + } + + public void Inspect(bool doCopy, bool isReadOnly, string directoryToInspect, string destination, bool dontAppendSubFolder, bool dontDeleteEmptyFolders, bool dontRunPreScripts) + { + Configuration.Inspector.IsInReadOnlyMode = isReadOnly; + Configuration.Inspector.DoCopyFiles = doCopy; + + var artistsFound = new List(); + var releasesFound = new List(); + var mp3FilesFoundCount = 0; + + Trace.Listeners.Add(new LoggingTraceListener()); + + PrintInspectorBanner(directoryToInspect); + string scriptResult = null; // Run PreInspect script dontRunPreScripts = File.Exists(Configuration.Processing.PreInspectScript) && dontRunPreScripts; @@ -366,7 +408,7 @@ public void Inspect(bool doCopy, bool isReadOnly, string directoryToInspect, str // Run directory plugins against current directory foreach (var plugin in DirectoryPlugins.Where(x => !x.IsPostProcessingPlugin).OrderBy(x => x.Order)) { - Console.WriteLine($"╠╬═ Running Directory Plugin {plugin.Description}"); + Console.WriteLine($"╠╬═ Running Directory Plugin: {plugin.Description}"); var pluginResult = plugin.Process(directoryInfo); if (!pluginResult.IsSuccess) { @@ -662,12 +704,12 @@ public class LoggingTraceListener : TraceListener { public override void Write(string message) { - Console.WriteLine($"╠╬═ { message }"); + Console.WriteLine($"╠╬═ {message}"); } public override void WriteLine(string message) { - Console.WriteLine($"╠╬═ { message }"); + Console.WriteLine($"╠╬═ {message}"); } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Inspect/Plugins/Directory/DeleteUnwantedFiles.cs b/Roadie.Api.Library/Inspect/Plugins/Directory/DeleteUnwantedFiles.cs index f06c799..3089af9 100644 --- a/Roadie.Api.Library/Inspect/Plugins/Directory/DeleteUnwantedFiles.cs +++ b/Roadie.Api.Library/Inspect/Plugins/Directory/DeleteUnwantedFiles.cs @@ -50,4 +50,4 @@ public override OperationResult Process(DirectoryInfo directory) return result; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureArtistConsistent.cs b/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureArtistConsistent.cs index 493345a..3f3f2e6 100644 --- a/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureArtistConsistent.cs +++ b/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureArtistConsistent.cs @@ -64,4 +64,4 @@ public override OperationResult Process(DirectoryInfo directory) return result; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureReleaseConsistent.cs b/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureReleaseConsistent.cs index 209c350..1703bc5 100644 --- a/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureReleaseConsistent.cs +++ b/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureReleaseConsistent.cs @@ -53,4 +53,4 @@ public override OperationResult Process(DirectoryInfo directory) return result; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureYearConsistent.cs b/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureYearConsistent.cs index 3d5ac2e..f42d0b9 100644 --- a/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureYearConsistent.cs +++ b/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureYearConsistent.cs @@ -52,4 +52,4 @@ public override OperationResult Process(DirectoryInfo directory) return result; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Inspect/Plugins/Directory/FolderPluginBase.cs b/Roadie.Api.Library/Inspect/Plugins/Directory/FolderPluginBase.cs index cfda328..63a2dd7 100644 --- a/Roadie.Api.Library/Inspect/Plugins/Directory/FolderPluginBase.cs +++ b/Roadie.Api.Library/Inspect/Plugins/Directory/FolderPluginBase.cs @@ -20,4 +20,4 @@ public FolderPluginBase(IRoadieSettings configuration, ICacheManager cacheManage public abstract OperationResult Process(DirectoryInfo directory); } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Inspect/Plugins/Directory/IInspectorDirectoryPlugin.cs b/Roadie.Api.Library/Inspect/Plugins/Directory/IInspectorDirectoryPlugin.cs index 15697c9..3a4ee84 100644 --- a/Roadie.Api.Library/Inspect/Plugins/Directory/IInspectorDirectoryPlugin.cs +++ b/Roadie.Api.Library/Inspect/Plugins/Directory/IInspectorDirectoryPlugin.cs @@ -14,4 +14,4 @@ public interface IInspectorDirectoryPlugin OperationResult Process(DirectoryInfo directory); } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Inspect/Plugins/Directory/RoadieDataFileCreator.cs b/Roadie.Api.Library/Inspect/Plugins/Directory/RoadieDataFileCreator.cs new file mode 100644 index 0000000..fa87aa8 --- /dev/null +++ b/Roadie.Api.Library/Inspect/Plugins/Directory/RoadieDataFileCreator.cs @@ -0,0 +1,147 @@ +using Microsoft.Extensions.Logging; +using Roadie.Library.Caching; +using Roadie.Library.Configuration; +using Roadie.Library.Extensions; +using Roadie.Library.MetaData.ID3Tags; +using Roadie.Library.Models; +using Roadie.Library.Models.Releases; +using Roadie.Library.Utility; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; + +namespace Roadie.Library.Inspect.Plugins.Directory +{ + public class RoadieDataFileCreator : FolderPluginBase + { + public static string RoadieDataFileCreatorDescription = "Creates Roadie JSON file(s) for the Directory."; + + public RoadieDataFileCreator( + IRoadieSettings configuration, + ICacheManager cacheManager, + ILogger logger, + IID3TagsHelper tagsHelper) + : base(configuration, cacheManager, logger, tagsHelper) + { + } + + public override string Description => RoadieDataFileCreatorDescription; + + public override int Order => 999; + + public override OperationResult Process(DirectoryInfo directory) + { + var result = new OperationResult(); + var data = new StringBuilder(); + + var stopWatch = Stopwatch.StartNew(); + + // Get all MP3 Files in the given folder and group by Artist Name + var mp3Files = directory.GetFiles("*.mp3", SearchOption.AllDirectories); + + var mp3TagDatas = new List(); + var invalidMp3sFound = new List(); + foreach (var fileInfo in mp3Files) + { + var tagLib = TagsHelper.MetaDataForFile(fileInfo.FullName, true); + if (!tagLib?.IsSuccess ?? false) + { + Console.ForegroundColor = ConsoleColor.DarkYellow; + data.AppendLine($"╟ ❗ INVALID: Missing: {ID3TagsHelper.DetermineMissingRequiredMetaData(tagLib.Data)}"); + invalidMp3sFound.Add(fileInfo.FullName); + } + else + { + mp3TagDatas.Add(tagLib.Data); + } + } + + if (invalidMp3sFound.Count > 0) + { + result.IsSuccess = false; + } + else + { + var now = DateTime.UtcNow; + var mp3TagDatasGroupsByRelease = mp3TagDatas.GroupBy(x => x.Release); + foreach (var mp3TagRelease in mp3TagDatasGroupsByRelease) + { + DateTime? releaseDate = null; + var releaseYear = mp3TagRelease.Where(x => x.Year > 0).FirstOrDefault()?.Year; + if (releaseYear.HasValue && releaseYear > 0) + { + releaseDate = new DateTime(releaseYear.Value, 1, 1); + } + var releaseData = new ReleaseList + { + Artist = new Models.DataToken + { + Value = Inspector.ToToken(mp3TagRelease.First().Artist), + Text = mp3TagRelease.First().Artist + }, + Release = new Models.DataToken + { + Value = Inspector.ToToken(mp3TagRelease.Key), + Text = mp3TagRelease.Key + }, + CreatedDate = now, + Id = Guid.NewGuid(), + MediaCount = mp3TagDatas.Select(x => x.Disc ?? 0).Distinct().Count(), + ReleaseDateDateTime = releaseDate, + Status = Enums.Statuses.New, + TrackCount = mp3TagRelease.Count() + }; + var medias = new List>(); + foreach (var mp3TagData in mp3TagDatas.GroupBy(x => x.Disc)) + { + var mediaTracks = mp3TagDatas.Where(x => x.Disc == mp3TagData.Key); + medias.Add(new ReleaseMediaList + { + MediaNumber = SafeParser.ToNumber(mp3TagData.Key) ?? 1, + TrackCount = mediaTracks.Count(), + SubTitle = mp3TagData.First().DiscSubTitle, + Tracks = mediaTracks.OrderBy(x => x.TrackNumber).Select(x => new Models.TrackListWithFileName + { + CreatedDate = x.FileInfo.CreationTimeUtc, + Duration = SafeParser.ToNumber(x.Time?.TotalMilliseconds), + FileHash = HashHelper.GetHash(x.FileInfo.FullName).ToString(), + FileName = x.FileInfo.FullName, + FileSize = SafeParser.ToNumber(x.FileInfo.Length), + Id = Guid.NewGuid(), + Status = Enums.Statuses.New, + Title = x.Title, + TrackArtist = string.IsNullOrWhiteSpace(x.TrackArtist) || string.Equals(releaseData.Artist.Value, x.TrackArtist, StringComparison.OrdinalIgnoreCase) ? null : new Models.ArtistList + { + Artist = new Models.DataToken + { + Value = Inspector.ToToken(x.TrackArtist), + Text = x.TrackArtist + } + }, + TrackNumber = x.TrackNumber + }).ToArray() + }); + } + releaseData.Media = medias; + releaseData.Status = releaseData.Media.SelectMany(x => x.Tracks).Count() == releaseData.Media.Sum(x => x.TrackCount) ? Enums.Statuses.Ok : Enums.Statuses.Incomplete; + releaseData.Duration = medias.SelectMany(x => x.Tracks).Sum(x => x.Duration); + var roadieDataFilenameByRelease = $"{releaseData.Artist.Text.ToFileNameFriendly()}."; + if (mp3TagDatasGroupsByRelease.Count() == 1) + { + roadieDataFilenameByRelease = null; + } + var roadieDataFileName = Path.Combine(directory.FullName, $"roadie.data.{roadieDataFilenameByRelease}json"); + System.IO.File.WriteAllText(roadieDataFileName, CacheManager.CacheSerializer.Serialize(releaseData)); + stopWatch.Stop(); + data.Append($"Created [{roadieDataFileName}] data json file, elapsed Time [{ stopWatch.ElapsedMilliseconds }]."); + } + result.IsSuccess = true; + } + result.Data = data.ToString(); + return result; + } + } +} diff --git a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpArtists.cs b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpArtists.cs index 9ef5a84..fc86a07 100644 --- a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpArtists.cs +++ b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpArtists.cs @@ -1,5 +1,4 @@ -using MetadataExtractor; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Roadie.Library.Caching; using Roadie.Library.Configuration; using Roadie.Library.Extensions; @@ -44,11 +43,11 @@ public string CleanArtist(string artist, string trackArtist = null) result = result.Replace(splitCharacter + trackArtist, string.Empty, StringComparison.OrdinalIgnoreCase); result = result.Replace(trackArtist, string.Empty, StringComparison.OrdinalIgnoreCase); } - if(Configuration.Processing.DoDetectFeatureFragments) + if (Configuration.Processing.DoDetectFeatureFragments) { - if(!string.IsNullOrWhiteSpace(result)) + if (!string.IsNullOrWhiteSpace(result)) { - if(result.HasFeaturingFragments()) + if (result.HasFeaturingFragments()) { throw new RoadieProcessingException($"Artist name [{ result }] has Feature fragments."); } @@ -71,4 +70,4 @@ public override OperationResult Process(AudioMetaData metaData) return result; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpComments.cs b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpComments.cs index 70ae4ca..e9d8c6b 100644 --- a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpComments.cs +++ b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpComments.cs @@ -34,4 +34,4 @@ public override OperationResult Process(AudioMetaData metaData) return result; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpReleaseTitle.cs b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpReleaseTitle.cs index 88cb03e..05deee3 100644 --- a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpReleaseTitle.cs +++ b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpReleaseTitle.cs @@ -47,4 +47,4 @@ public override OperationResult Process(AudioMetaData metaData) return result; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpTrackTitle.cs b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpTrackTitle.cs index f300b74..adce4bd 100644 --- a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpTrackTitle.cs +++ b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpTrackTitle.cs @@ -47,4 +47,4 @@ public override OperationResult Process(AudioMetaData metaData) return result; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Inspect/Plugins/File/EnsureFileWriteable.cs b/Roadie.Api.Library/Inspect/Plugins/File/EnsureFileWriteable.cs index 0347f6c..0484c8d 100644 --- a/Roadie.Api.Library/Inspect/Plugins/File/EnsureFileWriteable.cs +++ b/Roadie.Api.Library/Inspect/Plugins/File/EnsureFileWriteable.cs @@ -43,4 +43,4 @@ public override OperationResult Process(AudioMetaData metaData) return result; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Inspect/Plugins/File/FilePluginBase.cs b/Roadie.Api.Library/Inspect/Plugins/File/FilePluginBase.cs index 1d26d59..4ee868c 100644 --- a/Roadie.Api.Library/Inspect/Plugins/File/FilePluginBase.cs +++ b/Roadie.Api.Library/Inspect/Plugins/File/FilePluginBase.cs @@ -18,4 +18,4 @@ public FilePluginBase(IRoadieSettings configuration, ICacheManager cacheManager, public abstract OperationResult Process(AudioMetaData metaData); } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Inspect/Plugins/File/IInspectorFilePlugin.cs b/Roadie.Api.Library/Inspect/Plugins/File/IInspectorFilePlugin.cs index 41c4b1f..59e67f0 100644 --- a/Roadie.Api.Library/Inspect/Plugins/File/IInspectorFilePlugin.cs +++ b/Roadie.Api.Library/Inspect/Plugins/File/IInspectorFilePlugin.cs @@ -12,4 +12,4 @@ public interface IInspectorFilePlugin OperationResult Process(AudioMetaData metaData); } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Inspect/Plugins/File/Renumber.cs b/Roadie.Api.Library/Inspect/Plugins/File/Renumber.cs index fbf90d5..3fafa98 100644 --- a/Roadie.Api.Library/Inspect/Plugins/File/Renumber.cs +++ b/Roadie.Api.Library/Inspect/Plugins/File/Renumber.cs @@ -35,4 +35,4 @@ public override OperationResult Process(AudioMetaData metaData) return result; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Inspect/Plugins/PluginBase.cs b/Roadie.Api.Library/Inspect/Plugins/PluginBase.cs index 0c9bd05..e2f31d6 100644 --- a/Roadie.Api.Library/Inspect/Plugins/PluginBase.cs +++ b/Roadie.Api.Library/Inspect/Plugins/PluginBase.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; namespace Roadie.Library.Inspect.Plugins { @@ -65,4 +64,4 @@ protected IEnumerable GetAudioMetaDatasForDirectory(DirectoryInfo return new AudioMetaData[0]; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/Models/Artist.cs b/Roadie.Api.Library/Models/Artist.cs index 01954e6..d50dcd3 100644 --- a/Roadie.Api.Library/Models/Artist.cs +++ b/Roadie.Api.Library/Models/Artist.cs @@ -16,7 +16,7 @@ public class Artist : EntityModelBase { public const string DefaultIncludes = "stats,images,associatedartists,similarartists,comments,collections,playlists,contributions,labels,genres"; - public IEnumerable ArtistContributionReleases; + public IEnumerable> ArtistContributionReleases; public IEnumerable ArtistLabels; private IEnumerable _isniList; [MaxLength(100)] public string AmgId { get; set; } @@ -97,7 +97,7 @@ public IEnumerable ISNIList [MaxLength(500)] public string RealName { get; set; } - public IEnumerable Releases { get; set; } + public IEnumerable> Releases { get; set; } public IEnumerable SimilarArtists { get; set; } diff --git a/Roadie.Api.Library/Models/BookmarkList.cs b/Roadie.Api.Library/Models/BookmarkList.cs index 9bb851d..f2944da 100644 --- a/Roadie.Api.Library/Models/BookmarkList.cs +++ b/Roadie.Api.Library/Models/BookmarkList.cs @@ -20,7 +20,7 @@ public sealed class BookmarkList : EntityInfoModelBase public LabelList Label { get; set; } public PlaylistList Playlist { get; set; } public int? Position { get; set; } - public ReleaseList Release { get; set; } + public ReleaseList Release { get; set; } public Image Thumbnail { get; set; } public TrackList Track { get; set; } public BookmarkType? Type { get; set; } diff --git a/Roadie.Api.Library/Models/Collections/CollectionRelease.cs b/Roadie.Api.Library/Models/Collections/CollectionRelease.cs index cdad320..be6c345 100644 --- a/Roadie.Api.Library/Models/Collections/CollectionRelease.cs +++ b/Roadie.Api.Library/Models/Collections/CollectionRelease.cs @@ -7,6 +7,6 @@ namespace Roadie.Library.Models.Collections public class CollectionRelease { public int ListNumber { get; set; } - public ReleaseList Release { get; set; } + public ReleaseList Release { get; set; } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Models/EntityInfoModelBase.cs b/Roadie.Api.Library/Models/EntityInfoModelBase.cs index 0ee28e3..4c99a66 100644 --- a/Roadie.Api.Library/Models/EntityInfoModelBase.cs +++ b/Roadie.Api.Library/Models/EntityInfoModelBase.cs @@ -17,7 +17,7 @@ public abstract class EntityInfoModelBase /// [AdaptIgnore] [JsonIgnore] - public int DatabaseId { get; set; } + public virtual int DatabaseId { get; set; } [Key] [Required] diff --git a/Roadie.Api.Library/Models/Player/PlayResultTrack.cs b/Roadie.Api.Library/Models/Player/PlayResultTrack.cs index e5e032c..dcbca8f 100644 --- a/Roadie.Api.Library/Models/Player/PlayResultTrack.cs +++ b/Roadie.Api.Library/Models/Player/PlayResultTrack.cs @@ -13,7 +13,7 @@ public class PlayResultTrack public int? Duration => Track.Duration; - public ReleaseList Release { get; set; } + public ReleaseList Release { get; set; } public string ShowArtistId => Track.TrackArtist?.Artist.Text ?? Artist.Artist.Text; diff --git a/Roadie.Api.Library/Models/Releases/Release.cs b/Roadie.Api.Library/Models/Releases/Release.cs index 184a3ed..76f11b7 100644 --- a/Roadie.Api.Library/Models/Releases/Release.cs +++ b/Roadie.Api.Library/Models/Releases/Release.cs @@ -41,7 +41,7 @@ public class Release : EntityModelBase public short MaxMediaNumber { get; set; } public short? MediaCount { get; set; } - public List Medias { get; set; } + public List> Medias { get; set; } public Image MediumThumbnail { get; set; } [MaxLength(100)] public string MusicBrainzId { get; set; } diff --git a/Roadie.Api.Library/Models/Releases/ReleaseList.cs b/Roadie.Api.Library/Models/Releases/ReleaseList.cs index e1f7f05..1ce796b 100644 --- a/Roadie.Api.Library/Models/Releases/ReleaseList.cs +++ b/Roadie.Api.Library/Models/Releases/ReleaseList.cs @@ -11,7 +11,7 @@ namespace Roadie.Library.Models.Releases { [Serializable] [DebuggerDisplay("DatabaseId [{ DatabaseId }] Name [{ ReleaseName }] IsValid [{ IsValid }]")] - public sealed class ReleaseList : EntityInfoModelBase + public sealed class ReleaseList : EntityInfoModelBase { public DataToken Artist { get; set; } @@ -55,7 +55,7 @@ public bool IsValid /// public int? ListNumber { get; set; } - public IEnumerable Media { get; set; } + public IEnumerable> Media { get; set; } public int? MediaCount { get; set; } @@ -94,10 +94,10 @@ public bool IsValid public UserRelease UserRating { get; set; } - public static ReleaseList FromDataRelease(Data.Release release, Data.Artist artist, string baseUrl, + public static ReleaseList FromDataRelease(Data.Release release, Data.Artist artist, string baseUrl, Image artistThumbnail, Image thumbnail) { - return new ReleaseList + return new ReleaseList { DatabaseId = release.Id, Id = release.RoadieId, @@ -129,9 +129,9 @@ public static ReleaseList FromDataRelease(Data.Release release, Data.Artist arti }; } - public ReleaseList ShallowCopy() + public ReleaseList ShallowCopy() { - return (ReleaseList)MemberwiseClone(); + return (ReleaseList)MemberwiseClone(); } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Models/Releases/ReleaseMediaList.cs b/Roadie.Api.Library/Models/Releases/ReleaseMediaList.cs index 60fe13c..1e0e48f 100644 --- a/Roadie.Api.Library/Models/Releases/ReleaseMediaList.cs +++ b/Roadie.Api.Library/Models/Releases/ReleaseMediaList.cs @@ -5,11 +5,11 @@ namespace Roadie.Library.Models.Releases { [Serializable] - public sealed class ReleaseMediaList : EntityInfoModelBase + public sealed class ReleaseMediaList : EntityInfoModelBase { public short? MediaNumber { get; set; } public string SubTitle { get; set; } public int? TrackCount { get; set; } - public IEnumerable Tracks { get; set; } = new TrackList[0]; + public IEnumerable Tracks { get; set; } = Enumerable.Empty(); } } \ No newline at end of file diff --git a/Roadie.Api.Library/Models/Statistics/UserStatistics.cs b/Roadie.Api.Library/Models/Statistics/UserStatistics.cs index 367f3e6..c24d726 100644 --- a/Roadie.Api.Library/Models/Statistics/UserStatistics.cs +++ b/Roadie.Api.Library/Models/Statistics/UserStatistics.cs @@ -13,7 +13,7 @@ public class UserStatistics public int? FavoritedReleases { get; set; } public int? FavoritedTracks { get; set; } public ArtistList MostPlayedArtist { get; set; } - public ReleaseList MostPlayedRelease { get; set; } + public ReleaseList MostPlayedRelease { get; set; } public TrackList MostPlayedTrack { get; set; } public TrackList LastPlayedTrack { get; set; } diff --git a/Roadie.Api.Library/Models/Track.cs b/Roadie.Api.Library/Models/Track.cs index 4be8a15..61fd056 100644 --- a/Roadie.Api.Library/Models/Track.cs +++ b/Roadie.Api.Library/Models/Track.cs @@ -91,7 +91,7 @@ public IEnumerable PartTitlesList public short Rating { get; set; } - public ReleaseList Release { get; set; } + public ReleaseList Release { get; set; } public string ReleaseMediaId { get; set; } diff --git a/Roadie.Api.Library/Models/TrackList.cs b/Roadie.Api.Library/Models/TrackList.cs index 93f0277..1983779 100644 --- a/Roadie.Api.Library/Models/TrackList.cs +++ b/Roadie.Api.Library/Models/TrackList.cs @@ -15,7 +15,7 @@ namespace Roadie.Library.Models { [Serializable] [DebuggerDisplay("Trackid [{ TrackId }], Track Name [{ TrackName }}, Release Name [{ ReleaseName }]")] - public sealed class TrackList : EntityInfoModelBase + public class TrackList : EntityInfoModelBase { public ArtistList Artist { get; set; } @@ -55,7 +55,7 @@ public IEnumerable PartTitlesList public short? Rating { get; set; } - public ReleaseList Release { get; set; } + public ReleaseList Release { get; set; } [JsonIgnore] public DateTime? ReleaseDate { get; set; } @@ -141,7 +141,7 @@ public static TrackList FromDataTrack(string trackPlayUrl, Text = track.Title, Value = track.RoadieId.ToString() }, - Release = ReleaseList.FromDataRelease(release, artist, baseUrl, artistThumbnail, releaseThumbnail), + Release = ReleaseList.FromDataRelease(release, artist, baseUrl, artistThumbnail, releaseThumbnail), LastPlayed = track.LastPlayed, Artist = ArtistList.FromDataArtist(artist, artistThumbnail), TrackArtist = trackArtist == null ? null : ArtistList.FromDataArtist(trackArtist, trackArtistThumbnail), diff --git a/Roadie.Api.Library/Models/TrackListWithFileName.cs b/Roadie.Api.Library/Models/TrackListWithFileName.cs new file mode 100644 index 0000000..ae2a206 --- /dev/null +++ b/Roadie.Api.Library/Models/TrackListWithFileName.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Roadie.Library.Models +{ + [Serializable] + [DebuggerDisplay("Trackid [{ TrackId }], Track Name [{ TrackName }}, Release Name [{ ReleaseName }]")] + public sealed class TrackListWithFileName : TrackList + { + public new int? DatabaseId { get; set; } + + public string FileName { get; set; } + + public string FileHash { get; set; } + } +} diff --git a/Roadie.Api.Library/SearchEngines/Imaging/BingImageResultModels.cs b/Roadie.Api.Library/SearchEngines/Imaging/BingImageResultModels.cs index dff51c1..aee453c 100644 --- a/Roadie.Api.Library/SearchEngines/Imaging/BingImageResultModels.cs +++ b/Roadie.Api.Library/SearchEngines/Imaging/BingImageResultModels.cs @@ -7,20 +7,30 @@ namespace Roadie.Library.SearchEngines.Imaging.BingModels public class BingImageResult { public string _type { get; set; } + public bool? displayRecipeSourcesBadges { get; set; } + public bool? displayShoppingSourcesBadges { get; set; } + public Instrumentation instrumentation { get; set; } + public int nextOffsetAddCount { get; set; } + public List pivotSuggestions { get; set; } + public List queryExpansions { get; set; } + public int? totalEstimatedMatches { get; set; } + public List value { get; set; } + public string webSearchUrl { get; set; } } public class Insightssourcessummary { public int? recipeSourcesCount { get; set; } + public int? shoppingSourcesCount { get; set; } } @@ -33,30 +43,40 @@ public class Instrumentation public class Pivotsuggestion { public string pivot { get; set; } + public List suggestions { get; set; } } public class Queryexpansion { public string displayText { get; set; } + public string searchLink { get; set; } + public string text { get; set; } + public Thumbnail1 thumbnail { get; set; } + public string webSearchUrl { get; set; } } public class Suggestion { public string displayText { get; set; } + public string searchLink { get; set; } + public string text { get; set; } + public Thumbnail2 thumbnail { get; set; } + public string webSearchUrl { get; set; } } public class Thumbnail { public int? height { get; set; } + public int? width { get; set; } } @@ -74,20 +94,35 @@ public class Thumbnail2 public class Value { public string accentColor { get; set; } + public string contentSize { get; set; } + public string contentUrl { get; set; } + public DateTime? datePublished { get; set; } + public string encodingFormat { get; set; } + public int? height { get; set; } + public string hostPageDisplayUrl { get; set; } + public string hostPageUrl { get; set; } + public string imageId { get; set; } + public string imageInsightsToken { get; set; } + public Insightssourcessummary insightsSourcesSummary { get; set; } + public string name { get; set; } + public Thumbnail thumbnail { get; set; } + public string thumbnailUrl { get; set; } + public string webSearchUrl { get; set; } + public int? width { get; set; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/Imaging/BingImageSearchEngine.cs b/Roadie.Api.Library/SearchEngines/Imaging/BingImageSearchEngine.cs index 31eaba6..ee943fb 100644 --- a/Roadie.Api.Library/SearchEngines/Imaging/BingImageSearchEngine.cs +++ b/Roadie.Api.Library/SearchEngines/Imaging/BingImageSearchEngine.cs @@ -16,7 +16,6 @@ namespace Roadie.Library.SearchEngines.Imaging /// public class BingImageSearchEngine : ImageSearchEngineBase, IBingImageSearchEngine { - public override bool IsEnabled => Configuration.Integrations.BingImageSearchEngineEnabled; public BingImageSearchEngine( @@ -76,4 +75,4 @@ public override async Task> PerformImageSearchAsy }).ToArray(); } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/Imaging/IBingImageSearchEngine.cs b/Roadie.Api.Library/SearchEngines/Imaging/IBingImageSearchEngine.cs index 4742b1c..3134d29 100644 --- a/Roadie.Api.Library/SearchEngines/Imaging/IBingImageSearchEngine.cs +++ b/Roadie.Api.Library/SearchEngines/Imaging/IBingImageSearchEngine.cs @@ -1,10 +1,6 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using RestSharp; - -namespace Roadie.Library.SearchEngines.Imaging +namespace Roadie.Library.SearchEngines.Imaging { public interface IBingImageSearchEngine : IImageSearchEngine { } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/Imaging/IITunesSearchEngine.cs b/Roadie.Api.Library/SearchEngines/Imaging/IITunesSearchEngine.cs index 3f521d2..8f4419e 100644 --- a/Roadie.Api.Library/SearchEngines/Imaging/IITunesSearchEngine.cs +++ b/Roadie.Api.Library/SearchEngines/Imaging/IITunesSearchEngine.cs @@ -1,11 +1,8 @@ -using RestSharp; -using Roadie.Library.SearchEngines.MetaData; -using System.Collections.Generic; -using System.Threading.Tasks; +using Roadie.Library.SearchEngines.MetaData; namespace Roadie.Library.SearchEngines.Imaging { public interface IITunesSearchEngine : IArtistSearchEngine, IReleaseSearchEngine, IImageSearchEngine { } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/Imaging/IImageSearchEngine.cs b/Roadie.Api.Library/SearchEngines/Imaging/IImageSearchEngine.cs index 1c7b3f7..a7b85ef 100644 --- a/Roadie.Api.Library/SearchEngines/Imaging/IImageSearchEngine.cs +++ b/Roadie.Api.Library/SearchEngines/Imaging/IImageSearchEngine.cs @@ -12,4 +12,4 @@ public interface IImageSearchEngine Task> PerformImageSearchAsync(string query, int resultsCount); } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/Imaging/IImageSearchManager.cs b/Roadie.Api.Library/SearchEngines/Imaging/IImageSearchManager.cs index 90118d4..32d9259 100644 --- a/Roadie.Api.Library/SearchEngines/Imaging/IImageSearchManager.cs +++ b/Roadie.Api.Library/SearchEngines/Imaging/IImageSearchManager.cs @@ -7,4 +7,4 @@ public interface IImageSearchManager { Task> ImageSearch(string query, int? resultsCount = null); } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/Imaging/ITunesImageSearchResultModels.cs b/Roadie.Api.Library/SearchEngines/Imaging/ITunesImageSearchResultModels.cs index fc393f3..d35bd25 100644 --- a/Roadie.Api.Library/SearchEngines/Imaging/ITunesImageSearchResultModels.cs +++ b/Roadie.Api.Library/SearchEngines/Imaging/ITunesImageSearchResultModels.cs @@ -6,32 +6,54 @@ namespace Roadie.Library.SearchEngines.Imaging public class ITunesSearchResult { public int resultCount { get; set; } + public List results { get; set; } } public class Result { public int amgArtistId { get; set; } + public int artistId { get; set; } + public string artistLinkUrl { get; set; } + public string artistName { get; set; } + public string artistType { get; set; } + public string artistViewUrl { get; set; } + public string artworkUrl100 { get; set; } + public string artworkUrl60 { get; set; } + public string collectionCensoredName { get; set; } + public string collectionExplicitness { get; set; } + public int collectionId { get; set; } + public string collectionName { get; set; } + public float collectionPrice { get; set; } + public string collectionType { get; set; } + public string collectionViewUrl { get; set; } + public string copyright { get; set; } + public string country { get; set; } + public string currency { get; set; } + public string primaryGenreName { get; set; } + public DateTime releaseDate { get; set; } + public int trackCount { get; set; } + public string wrapperType { get; set; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/Imaging/ITunesSearchEngine.cs b/Roadie.Api.Library/SearchEngines/Imaging/ITunesSearchEngine.cs index df52cf5..03d8216 100644 --- a/Roadie.Api.Library/SearchEngines/Imaging/ITunesSearchEngine.cs +++ b/Roadie.Api.Library/SearchEngines/Imaging/ITunesSearchEngine.cs @@ -189,4 +189,4 @@ private RestRequest BuildRequest(string query, int resultsCount, string entityTy return request; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/Imaging/ImageSearchEngineBase.cs b/Roadie.Api.Library/SearchEngines/Imaging/ImageSearchEngineBase.cs index 1776055..a606f74 100644 --- a/Roadie.Api.Library/SearchEngines/Imaging/ImageSearchEngineBase.cs +++ b/Roadie.Api.Library/SearchEngines/Imaging/ImageSearchEngineBase.cs @@ -12,10 +12,15 @@ namespace Roadie.Library.SearchEngines.Imaging public abstract class ImageSearchEngineBase : IImageSearchEngine { protected readonly RestClient _client; + protected readonly IRoadieSettings _configuratio; + protected readonly string _referrer; + protected readonly string _requestIp; + protected IApiKey _apiKey = null; + protected ILogger _logger; public abstract bool IsEnabled { get; } @@ -55,4 +60,4 @@ public virtual Task> PerformImageSearchAsync(stri throw new NotImplementedException(); } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/Imaging/ImageSearchManager.cs b/Roadie.Api.Library/SearchEngines/Imaging/ImageSearchManager.cs index bf9f877..74c9d11 100644 --- a/Roadie.Api.Library/SearchEngines/Imaging/ImageSearchManager.cs +++ b/Roadie.Api.Library/SearchEngines/Imaging/ImageSearchManager.cs @@ -12,7 +12,9 @@ namespace Roadie.Library.SearchEngines.Imaging public class ImageSearchManager : IImageSearchManager { private readonly IImageSearchEngine _bingSearchEngine; + private readonly IImageSearchEngine _itunesSearchEngine; + private readonly IHttpClientFactory _httpClientFactory; private IRoadieSettings Configuration { get; } @@ -63,4 +65,4 @@ public async Task> ImageSearch(string query, int? return result; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/Imaging/ImageSearchResult.cs b/Roadie.Api.Library/SearchEngines/Imaging/ImageSearchResult.cs index ef097bb..2969841 100644 --- a/Roadie.Api.Library/SearchEngines/Imaging/ImageSearchResult.cs +++ b/Roadie.Api.Library/SearchEngines/Imaging/ImageSearchResult.cs @@ -6,6 +6,7 @@ namespace Roadie.Library.SearchEngines.Imaging public class __Metadata { public string type { get; set; } + public string uri { get; set; } } @@ -13,17 +14,29 @@ public class __Metadata public class ImageSearchResult { public __Metadata __metadata { get; set; } + public string ArtistId { get; set; } + public string ArtistName { get; set; } + public string ContentType { get; set; } + public string DisplayUrl { get; set; } + public string FileSize { get; set; } + public string Height { get; set; } + public string ID { get; set; } + public string MediaUrl { get; set; } + public string SourceUrl { get; set; } + public Thumbnail Thumbnail { get; set; } + public string Title { get; set; } + public string Width { get; set; } } @@ -31,10 +44,15 @@ public class ImageSearchResult public class Thumbnail { public __Metadata __metadata { get; set; } + public string ContentType { get; set; } + public string FileSize { get; set; } + public string Height { get; set; } + public string MediaUrl { get; set; } + public string Width { get; set; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/MetaData/ArtistSearchResult.cs b/Roadie.Api.Library/SearchEngines/MetaData/ArtistSearchResult.cs index 8e8142a..cb73af2 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/ArtistSearchResult.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/ArtistSearchResult.cs @@ -7,14 +7,23 @@ namespace Roadie.Library.SearchEngines.MetaData public class ArtistSearchResult : SearchResultBase { public ICollection ArtistGenres { get; set; } + public string ArtistName { get; set; } + public string ArtistRealName { get; set; } + public string ArtistSortName { get; set; } + public string ArtistThumbnailUrl { get; set; } + public string ArtistType { get; set; } + public DateTime? BeginDate { get; set; } + public DateTime? BirthDate { get; set; } + public DateTime? EndDate { get; set; } + public ICollection Releases { get; set; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaData.cs b/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaData.cs index c0d7bb7..64c49a6 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaData.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaData.cs @@ -15,7 +15,9 @@ namespace Roadie.Library.MetaData.Audio public sealed class AudioMetaData : IAudioMetaData { public const char ArtistSplitCharacter = '/'; + public const int MinimumYearValue = 1900; + public const string SoundTrackArtist = "Sound Tracks"; private string _artist; @@ -399,4 +401,4 @@ public override string ToString() return result; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaDataHelper.cs b/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaDataHelper.cs index 6822228..20b141a 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaDataHelper.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaDataHelper.cs @@ -1,7 +1,6 @@ using Microsoft.Extensions.Logging; using Roadie.Library.Caching; using Roadie.Library.Configuration; -using Roadie.Library.Data; using Roadie.Library.Data.Context; using Roadie.Library.Encoding; using Roadie.Library.Engines; @@ -53,8 +52,8 @@ public sealed class AudioMetaDataHelper : IAudioMetaDataHelper private IMusicBrainzProvider MusicBrainzProvider { get; } public AudioMetaDataHelper(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context, - IMusicBrainzProvider musicBrainzHelper, ILastFmHelper lastFmHelper, ICacheManager cacheManager, - ILogger logger, IArtistLookupEngine artistLookupEngine, IFileNameHelper filenameHelper, + IMusicBrainzProvider musicBrainzHelper, ILastFmHelper lastFmHelper, ICacheManager cacheManager, + ILogger logger, IArtistLookupEngine artistLookupEngine, IFileNameHelper filenameHelper, IID3TagsHelper id3TagsHelper) { Configuration = configuration; @@ -113,7 +112,7 @@ public async Task GetInfo(FileInfo fileInfo, bool doJustInfo = fa if (!result.IsValid) { - Logger.LogWarning("File [{0}] MetaData Invalid, TagSources [{1}] MetaData [{2}]", fileInfo.FullName, string.Join(",", tagSources), result.ToString()); + Logger.LogWarning("File [{0}] MetaData Invalid, TagSources [{1}] MetaData [{2}]", fileInfo.FullName, string.Join(",", tagSources), result.ToString()); } else { @@ -265,4 +264,4 @@ private AudioMetaData ParseFromTags(FileInfo fileInfo) }; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaDataImage.cs b/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaDataImage.cs index 7e045f5..4481bce 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaDataImage.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaDataImage.cs @@ -3,9 +3,13 @@ public sealed class AudioMetaDataImage { public byte[] Data { get; set; } + public string Description { get; set; } + public string MimeType { get; set; } + public AudioMetaDataImageType Type { get; set; } + public string Url { get; set; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaDataImageType.cs b/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaDataImageType.cs index d1f166c..80f9bee 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaDataImageType.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaDataImageType.cs @@ -3,25 +3,45 @@ public enum AudioMetaDataImageType { Other = 0, + FileIcon = 1, + OtherFileIcon = 2, + FrontCover = 3, + BackCover = 4, + LeafletPage = 5, + Media = 6, + LeadArtist = 7, + Artist = 8, + Conductor = 9, + Band = 10, + Composer = 11, + Lyricist = 12, + RecordingLocation = 13, + DuringRecording = 14, + DuringPerformance = 15, + MovieScreenCapture = 16, + ColoredFish = 17, + Illustration = 18, + BandLogo = 19, + PublisherLogo = 20 } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudoMetaDataWeights.cs b/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudoMetaDataWeights.cs index b882ae6..0fe4f0e 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudoMetaDataWeights.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudoMetaDataWeights.cs @@ -6,12 +6,19 @@ namespace Roadie.Library.MetaData.Audio public enum AudioMetaDataWeights { None = 0, + Year = 1, + Time = 2, + TrackNumber = 4, + TrackTotalNumber = 8, + Release = 16, + Title = 32, + Artist = 64 } @@ -19,4 +26,4 @@ public enum AudioMetaDataWeights //Artist + Release + TrackNumber 44 //Artist + TrackNumber + Title 38 //Artist + Release + TrackNumber + TrackTitle = 60 -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/MetaData/Audio/IAudioMetaData.cs b/Roadie.Api.Library/SearchEngines/MetaData/Audio/IAudioMetaData.cs index 68abfcb..cd30124 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/Audio/IAudioMetaData.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/Audio/IAudioMetaData.cs @@ -7,41 +7,77 @@ namespace Roadie.Library.MetaData.Audio public interface IAudioMetaData { string AmgId { get; set; } + string Artist { get; set; } + string ArtistRaw { get; set; } + int? AudioBitrate { get; set; } + int? AudioChannels { get; set; } + AudioMetaDataWeights AudioMetaDataWeights { get; } + int? AudioSampleRate { get; set; } + string Comments { get; set; } + string Directory { get; } + int? Disc { get; set; } + string DiscSubTitle { get; set; } + FileInfo FileInfo { get; } + string Filename { get; set; } + ICollection Genres { get; set; } + IEnumerable Images { get; set; } + string ISRC { get; } + bool IsSoundTrack { get; } + bool IsValid { get; } + string LastFmId { get; set; } + string MusicBrainzId { get; set; } + string Release { get; set; } + string ReleaseLastFmId { get; set; } + string ReleaseMusicBrainzId { get; set; } + ulong? SampleLength { get; set; } + string SpecialTitle { get; set; } + string SpotifyId { get; set; } + TimeSpan? Time { get; set; } + string Title { get; set; } + int? TotalDiscCount { get; set; } + double TotalSeconds { get; } + int? TotalTrackNumbers { get; set; } + string TrackArtist { get; set; } + string TrackArtistRaw { get; set; } + IEnumerable TrackArtists { get; } + short? TrackNumber { get; set; } + int ValidWeight { get; } + int? Year { get; set; } bool Equals(object obj); @@ -52,4 +88,4 @@ public interface IAudioMetaData string ToString(); } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/MetaData/Audio/IAudioMetaDataHelper.cs b/Roadie.Api.Library/SearchEngines/MetaData/Audio/IAudioMetaDataHelper.cs index e965d16..acd6afa 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/Audio/IAudioMetaDataHelper.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/Audio/IAudioMetaDataHelper.cs @@ -6,13 +6,17 @@ namespace Roadie.Library.MetaData.Audio public interface IAudioMetaDataHelper { bool DoParseFromDiscogsDB { get; set; } + bool DoParseFromDiscogsDBFindingTrackForArtist { get; set; } + bool DoParseFromFileName { get; set; } + bool DoParseFromLastFM { get; set; } + bool DoParseFromMusicBrainz { get; set; } Task GetInfo(FileInfo fileInfo, bool doJustInfo = false); bool WriteTags(AudioMetaData metaData, FileInfo fileInfo); } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/MetaData/Discogs/DiscogsHelper.cs b/Roadie.Api.Library/SearchEngines/MetaData/Discogs/DiscogsHelper.cs index b4fe127..3945a17 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/Discogs/DiscogsHelper.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/Discogs/DiscogsHelper.cs @@ -23,8 +23,8 @@ public DiscogsHelper( IRoadieSettings configuration, ICacheManager cacheManager, ILogger logger, - IHttpClientFactory httpClientFactory) : base( - configuration, cacheManager, logger, httpClientFactory) + IHttpClientFactory httpClientFactory) + : base(configuration, cacheManager, logger, httpClientFactory) { _apiKey = configuration.Integrations.ApiKeys.FirstOrDefault(x => x.ApiName == "DiscogsConsumerKey") ?? new ApiKey(); } @@ -41,8 +41,8 @@ public async Task>> PerformArtis var request = BuildSearchRequest(query, 1, "artist"); var client = new RestClient(new RestClientOptions("https://api.discogs.com/database") - { - UserAgent = WebHelper.UserAgent + { + UserAgent = WebHelper.UserAgent }); var response = await client.ExecuteAsync(request).ConfigureAwait(false); @@ -392,4 +392,4 @@ private RestRequest BuildSearchRequest(string query, int resultsCount, string en return request; } } -} \ No newline at end of file +} diff --git a/Roadie.Api.Library/SearchEngines/MetaData/Discogs/Entities.cs b/Roadie.Api.Library/SearchEngines/MetaData/Discogs/Entities.cs index 92ccdbc..2d102f2 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/Discogs/Entities.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/Discogs/Entities.cs @@ -6,249 +6,378 @@ namespace Roadie.Library.SearchEngines.MetaData.Discogs public class Artist { public string anv { get; set; } + public int? id { get; set; } + public string join { get; set; } + public string name { get; set; } + public string resource_url { get; set; } + public string role { get; set; } + public string tracks { get; set; } } public class Community { public List contributors { get; set; } + public string data_quality { get; set; } + public int? have { get; set; } + public Rating rating { get; set; } + public string status { get; set; } + public Submitter submitter { get; set; } + public int? want { get; set; } } public class Company { public string catno { get; set; } + public string entity_type { get; set; } + public string entity_type_name { get; set; } + public int? id { get; set; } + public string name { get; set; } + public string resource_url { get; set; } } public class Contributor { public string resource_url { get; set; } + public string username { get; set; } } public class DiscogArtistResponse { public string data_quality { get; set; } + public List groups { get; set; } + public int? id { get; set; } + public List images { get; set; } + public string name { get; set; } + public List namevariations { get; set; } + public string profile { get; set; } + public string realname { get; set; } + public string releases_url { get; set; } + public string resource_url { get; set; } + public string uri { get; set; } + public List urls { get; set; } } public class DiscogReleaseDetail { public List artists { get; set; } + public Community community { get; set; } + public List companies { get; set; } + public string country { get; set; } + public string data_quality { get; set; } + public DateTime date_added { get; set; } + public DateTime date_changed { get; set; } + public int? estimated_weight { get; set; } + public List extraartists { get; set; } + public int? format_quantity { get; set; } + public List formats { get; set; } + public List genres { get; set; } + public int? id { get; set; } + public List identifiers { get; set; } + public List images { get; set; } + public List