Example #1
0
        public void FindDiscNumberShouldBeTwo(string filename)
        {
            var n = ID3TagsHelper.DetermineDiscNumber(new AudioMetaData {
                Filename = filename
            });

            Assert.Equal(2, n);
        }
Example #2
0
        public void Find_Disc_Number_Should_Be_One(string filename)
        {
            var n = ID3TagsHelper.DetermineDiscNumber(new AudioMetaData {
                Filename = filename
            });

            Assert.Equal(1, n);
        }
Example #3
0
        public override OperationResult <AudioMetaData> Process(AudioMetaData metaData)
        {
            var result = new OperationResult <AudioMetaData>();
            var metaDatasForFilesInFolder = GetAudioMetaDatasForDirectory(metaData.FileInfo.Directory);

            metaData.TrackNumber       = (metaData.TrackNumber ?? 0) > 0 ? metaData.TrackNumber : ID3TagsHelper.DetermineTrackNumber(metaData.FileInfo.Name);
            metaData.TotalTrackNumbers = ID3TagsHelper.DetermineTotalTrackNumbers(metaData.Filename) ?? metaDatasForFilesInFolder.Count();
            metaData.Disc           = ID3TagsHelper.DetermineDiscNumber(metaData);
            metaData.TotalDiscCount = ID3TagsHelper.DetermineTotalDiscNumbers(metaDatasForFilesInFolder);
            result.Data             = metaData;
            result.IsSuccess        = true;
            return(result);
        }
Example #4
0
        public override OperationResult <IEnumerable <AudioMetaData> > Process(IEnumerable <AudioMetaData> metaDatas)
        {
            var result             = new OperationResult <IEnumerable <AudioMetaData> >();
            var totalNumberOfMedia = ID3TagsHelper.DetermineTotalDiscNumbers(metaDatas);
            var folders            = metaDatas.GroupBy(x => x.FileInfo.DirectoryName);

            foreach (var folder in folders)
            {
                short looper = 0;
                foreach (var metaData in folder)
                {
                    looper++;
                    metaData.TrackNumber       = looper;
                    metaData.TotalTrackNumbers = ID3TagsHelper.DetermineTotalTrackNumbers(metaData.Filename) ?? folder.Count();
                    metaData.Disk           = ID3TagsHelper.DetermineDiscNumber(metaData);
                    metaData.TotalDiscCount = totalNumberOfMedia;
                }
            }
            result.Data      = metaDatas;
            result.IsSuccess = true;
            return(result);
        }
Example #5
0
        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 <string>();
            var releasesFound      = new List <string>();
            var mp3FilesFoundCount = 0;

            Trace.Listeners.Add(new LoggingTraceListener());

            Console.BackgroundColor = ConsoleColor.White;
            Console.ForegroundColor = ConsoleColor.Blue;
            Console.WriteLine($"✨ Inspector Start, UTC [{DateTime.UtcNow.ToString("s")}]");
            Console.ResetColor();

            string scriptResult = null;

            // Run PreInspect script
            if (dontRunPreScripts)
            {
                Console.BackgroundColor = ConsoleColor.Blue;
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine($"Skipping PreInspectScript.");
                Console.ResetColor();
            }
            else
            {
                scriptResult = RunScript(Configuration.Processing.PreInspectScript, doCopy, isReadOnly, directoryToInspect, destination);
                if (!string.IsNullOrEmpty(scriptResult))
                {
                    Console.BackgroundColor = ConsoleColor.Blue;
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.WriteLine($"PreInspectScript Results: {Environment.NewLine + scriptResult + Environment.NewLine}");
                    Console.ResetColor();
                }
            }
            // Create a new destination subfolder for each Inspector run by Current timestamp
            var dest = Path.Combine(destination, DateTime.UtcNow.ToString("yyyyMMddHHmm"));

            if (isReadOnly || dontAppendSubFolder)
            {
                dest = destination;
            }
            // Get all the directorys in the directory
            var directoryDirectories = Directory.GetDirectories(directoryToInspect, "*.*", SearchOption.AllDirectories);
            var directories          = new List <string>
            {
                directoryToInspect
            };

            directories.AddRange(directoryDirectories);
            directories.Remove(dest);
            var inspectedImagesInDirectories = new List <string>();

            try
            {
                var createdDestinationFolder = false;
                var sw = Stopwatch.StartNew();

                foreach (var directory in directories.OrderBy(x => x))
                {
                    var directoryInfo = new DirectoryInfo(directory);

                    Console.ForegroundColor = ConsoleColor.Blue;
                    Console.WriteLine($"╔ 📂 Inspecting [{directory}]");
                    Console.ResetColor();
                    Console.WriteLine("╠╦════════════════════════╣");

                    // Get all the MP3 files in 'directory'
                    var files = Directory.GetFiles(directory, "*.mp3", SearchOption.TopDirectoryOnly);
                    if (files != null && files.Any())
                    {
                        if (!isReadOnly && !createdDestinationFolder && !Directory.Exists(dest))
                        {
                            Directory.CreateDirectory(dest);
                            createdDestinationFolder = true;
                        }

                        // 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}");
                            var pluginResult = plugin.Process(directoryInfo);
                            if (!pluginResult.IsSuccess)
                            {
                                Console.WriteLine(
                                    $"📛 Plugin Failed: Error [{JsonConvert.SerializeObject(pluginResult)}]");
                                return;
                            }

                            if (!string.IsNullOrEmpty(pluginResult.Data))
                            {
                                Console.WriteLine($"╠╣ Directory Plugin Message: {pluginResult.Data}");
                            }
                        }

                        Console.WriteLine("╠╝");
                        Console.WriteLine($"╟─ Found [{files.Length}] mp3 Files");
                        var fileMetaDatas = new List <AudioMetaData>();
                        var fileInfos     = new List <FileInfo>();
                        // Inspect the found MP3 files in 'directory'
                        foreach (var file in files)
                        {
                            mp3FilesFoundCount++;
                            var fileInfo = new FileInfo(file);
                            Console.ForegroundColor = ConsoleColor.DarkGreen;
                            Console.WriteLine($"╟─ 🎵 Inspecting [{fileInfo.FullName}]");
                            var tagLib = TagsHelper.MetaDataForFile(fileInfo.FullName, true);
                            Console.ForegroundColor = ConsoleColor.Cyan;
                            if (!tagLib?.IsSuccess ?? false)
                            {
                                Console.ForegroundColor = ConsoleColor.DarkYellow;
                            }
                            Console.WriteLine($"╟ (Pre ) : {tagLib.Data}");
                            Console.ResetColor();
                            tagLib.Data.Filename = fileInfo.FullName;
                            var originalMetaData = tagLib.Data.Adapt <AudioMetaData>();
                            if (!originalMetaData.IsValid)
                            {
                                Console.ForegroundColor = ConsoleColor.DarkYellow;
                                Console.WriteLine(
                                    $"╟ ❗ INVALID: Missing: {ID3TagsHelper.DetermineMissingRequiredMetaData(originalMetaData)}");
                                Console.WriteLine($"╟ [{JsonConvert.SerializeObject(tagLib, Newtonsoft.Json.Formatting.Indented)}]");
                                Console.ResetColor();
                            }

                            var pluginMetaData = tagLib.Data;
                            // Run all file plugins against the MP3 file modifying the MetaData
                            foreach (var plugin in FilePlugins.OrderBy(x => x.Order))
                            {
                                Console.WriteLine($"╟┤ Running File Plugin {plugin.Description}");
                                OperationResult <AudioMetaData> pluginResult = null;
                                pluginResult = plugin.Process(pluginMetaData);
                                if (!pluginResult.IsSuccess)
                                {
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    Console.WriteLine(
                                        $"📛 Plugin Failed: Error [{JsonConvert.SerializeObject(pluginResult)}]");
                                    Console.ResetColor();
                                    return;
                                }

                                pluginMetaData = pluginResult.Data;
                            }

                            if (!pluginMetaData.IsValid)
                            {
                                Console.ForegroundColor = ConsoleColor.Red;
                                Console.WriteLine(
                                    $"╟ ❗ INVALID: Missing: {ID3TagsHelper.DetermineMissingRequiredMetaData(pluginMetaData)}");
                                Console.ResetColor();
                                return;
                            }

                            // See if the MetaData from the Plugins is different from the original
                            if (originalMetaData != null && pluginMetaData != null)
                            {
                                var differences = Comparer.Compare(originalMetaData, pluginMetaData);
                                if (differences.Any())
                                {
                                    var skipDifferences = new List <string>
                                    {
                                        "AudioMetaDataWeights", "FileInfo", "Images", "TrackArtists"
                                    };
                                    var differencesDescription = $"{Environment.NewLine}";
                                    foreach (var difference in differences)
                                    {
                                        if (skipDifferences.Contains(difference.Name))
                                        {
                                            continue;
                                        }
                                        differencesDescription +=
                                            $"╟ || {difference.Name} : Was [{difference.OldValue}] Now [{difference.NewValue}]{Environment.NewLine}";
                                    }

                                    Console.Write($"╟ ≡ != ID3 Tag Modified: {differencesDescription}");

                                    if (!isReadOnly)
                                    {
                                        if (!TagsHelper.WriteTags(pluginMetaData, pluginMetaData.Filename))
                                        {
                                            Console.ForegroundColor = ConsoleColor.Red;
                                            Console.WriteLine("📛 WriteTags Failed");
                                            Console.ResetColor();
                                            return;
                                        }
                                    }
                                    else
                                    {
                                        Console.WriteLine("╟ 🔒 Read Only Mode: Not Modifying File ID3 Tags.");
                                    }
                                }
                                else
                                {
                                    Console.WriteLine("╟ ≡ == ID3 Tag NOT Modified");
                                }
                            }
                            else
                            {
                                var oBad = originalMetaData == null;
                                var pBad = pluginMetaData == null;
                                Console.WriteLine(
                                    $"╟ !! MetaData comparison skipped. {(oBad ? "Pre MetaData is Invalid" : "")} {(pBad ? "Post MetaData is Invalid" : "")}");
                            }

                            if (!pluginMetaData.IsValid)
                            {
                                Console.ForegroundColor = ConsoleColor.Red;
                                Console.WriteLine(
                                    $"╟ ❗ INVALID: Missing: {ID3TagsHelper.DetermineMissingRequiredMetaData(pluginMetaData)}");
                                Console.ResetColor();
                            }
                            else
                            {
                                Console.ForegroundColor = ConsoleColor.Cyan;
                                Console.WriteLine($"╟ (Post) : {pluginMetaData}");
                                Console.ResetColor();

                                var artistToken = ArtistInspectorToken(tagLib.Data);
                                if (!artistsFound.Contains(artistToken))
                                {
                                    artistsFound.Add(artistToken);
                                }
                                var releaseToken = ReleaseInspectorToken(tagLib.Data);
                                if (!releasesFound.Contains(releaseToken))
                                {
                                    releasesFound.Add(releaseToken);
                                }
                                var newFileName =
                                    $"CD{(tagLib.Data.Disc ?? ID3TagsHelper.DetermineDiscNumber(tagLib.Data)).ToString("000")}_{tagLib.Data.TrackNumber.Value.ToString("0000")}.mp3";
                                // Artist sub folder is created to hold Releases for Artist and Artist Images
                                var artistSubDirectory = directory == dest
                                    ? fileInfo.DirectoryName
                                    : Path.Combine(dest, artistToken);
                                // Each release is put into a subfolder into the current run Inspector folder to hold MP3 Files and Release Images
                                var subDirectory = directory == dest
                                    ? fileInfo.DirectoryName
                                    : Path.Combine(dest, artistToken, releaseToken);
                                if (!isReadOnly && !Directory.Exists(subDirectory))
                                {
                                    Directory.CreateDirectory(subDirectory);
                                }
                                // Inspect images
                                if (!inspectedImagesInDirectories.Contains(directoryInfo.FullName))
                                {
                                    // Get all artist images and move to artist folder
                                    var foundArtistImages = new List <FileInfo>();
                                    foundArtistImages.AddRange(ImageHelper.FindImagesByName(directoryInfo,
                                                                                            tagLib.Data.Artist, SearchOption.TopDirectoryOnly));
                                    foundArtistImages.AddRange(ImageHelper.FindImagesByName(directoryInfo.Parent,
                                                                                            tagLib.Data.Artist, SearchOption.TopDirectoryOnly));
                                    foundArtistImages.AddRange(ImageHelper.FindImageTypeInDirectory(
                                                                   directoryInfo.Parent, ImageType.Artist, SearchOption.TopDirectoryOnly));
                                    foundArtistImages.AddRange(ImageHelper.FindImageTypeInDirectory(
                                                                   directoryInfo.Parent, ImageType.ArtistSecondary,
                                                                   SearchOption.TopDirectoryOnly));
                                    foundArtistImages.AddRange(ImageHelper.FindImageTypeInDirectory(directoryInfo,
                                                                                                    ImageType.Artist, SearchOption.TopDirectoryOnly));
                                    foundArtistImages.AddRange(ImageHelper.FindImageTypeInDirectory(directoryInfo,
                                                                                                    ImageType.ArtistSecondary, SearchOption.TopDirectoryOnly));

                                    foreach (var artistImage in foundArtistImages)
                                    {
                                        InspectImage(isReadOnly, doCopy, dest, artistSubDirectory, artistImage);
                                    }

                                    // Get all release images and move to release folder
                                    var foundReleaseImages = new List <FileInfo>();
                                    foundReleaseImages.AddRange(
                                        ImageHelper.FindImagesByName(directoryInfo, tagLib.Data.Release));
                                    foundReleaseImages.AddRange(
                                        ImageHelper.FindImageTypeInDirectory(directoryInfo, ImageType.Release));
                                    foundReleaseImages.AddRange(
                                        ImageHelper.FindImageTypeInDirectory(directoryInfo,
                                                                             ImageType.ReleaseSecondary));
                                    foreach (var foundReleaseImage in foundReleaseImages)
                                    {
                                        InspectImage(isReadOnly, doCopy, dest, subDirectory, foundReleaseImage);
                                    }
                                    inspectedImagesInDirectories.Add(directoryInfo.FullName);
                                }

                                // If enabled move MP3 to new folder
                                var newPath = Path.Combine(dest, subDirectory, newFileName.ToFileNameFriendly());
                                if (isReadOnly)
                                {
                                    Console.WriteLine(
                                        $"╟ 🔒 Read Only Mode: File would be [{(doCopy ? "Copied" : "Moved")}] to [{newPath}]");
                                }
                                else
                                {
                                    if (!doCopy)
                                    {
                                        if (fileInfo.FullName != newPath)
                                        {
                                            if (File.Exists(newPath))
                                            {
                                                File.Delete(newPath);
                                            }
                                            fileInfo.MoveTo(newPath);
                                        }
                                    }
                                    else
                                    {
                                        fileInfo.CopyTo(newPath, true);
                                    }

                                    Console.ForegroundColor = ConsoleColor.DarkYellow;
                                    Console.WriteLine($"╠═ 🚛 {(doCopy ? "Copied" : "Moved")} MP3 File to [{newPath}]");
                                    Console.ResetColor();
                                }

                                Console.WriteLine("╠════════════════════════╣");
                            }
                        }
                    }
                }

                foreach (var directory in directories.OrderBy(x => x))
                {
                    var directoryInfo = new DirectoryInfo(directory);
                    Console.WriteLine($"╠╬═ Post-Processing Directory [{directoryInfo.FullName}] ");

                    // Run post-processing directory plugins against current directory
                    foreach (var plugin in DirectoryPlugins.Where(x => x.IsPostProcessingPlugin).OrderBy(x => x.Order))
                    {
                        Console.WriteLine($"╠╬═ Running Post-Processing Directory Plugin {plugin.Description}");
                        var pluginResult = plugin.Process(directoryInfo);
                        if (!pluginResult.IsSuccess)
                        {
                            Console.WriteLine($"📛 Plugin Failed: Error [{JsonConvert.SerializeObject(pluginResult)}]");
                            return;
                        }

                        if (!string.IsNullOrEmpty(pluginResult.Data))
                        {
                            Console.WriteLine($"╠╣ Directory Plugin Message: {pluginResult.Data}");
                        }
                    }
                }

                Console.WriteLine("╠╝");
                sw.Stop();
                Console.WriteLine(
                    $"╚═ Elapsed Time {sw.ElapsedMilliseconds.ToString("0000000")}, Artists {artistsFound.Count()}, Releases {releasesFound.Count()}, MP3s {mp3FilesFoundCount} ═╝");
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                Console.WriteLine("📛 Exception: " + ex);
            }

            if (!dontDeleteEmptyFolders)
            {
                var delEmptyFolderIn = new DirectoryInfo(directoryToInspect);
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine($"❌ Deleting Empty folders in [{delEmptyFolderIn.FullName}]");
                Console.ResetColor();
                FolderPathHelper.DeleteEmptyFolders(delEmptyFolderIn);
            }
            else
            {
                Console.WriteLine("🔒 Read Only Mode: Not deleting empty folders.");
            }

            // Run PreInspect script
            scriptResult = RunScript(Configuration.Processing.PostInspectScript, doCopy, isReadOnly, directoryToInspect, destination);
            if (!string.IsNullOrEmpty(scriptResult))
            {
                Console.BackgroundColor = ConsoleColor.Blue;
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine(
                    $"PostInspectScript Results: {Environment.NewLine + scriptResult + Environment.NewLine}");
                Console.ResetColor();
            }
        }
Example #6
0
        public void Inspect(bool doCopy, string folder, string destination)
        {
            // Get all the directorys in the directory
            var folderDirectories = Directory.GetDirectories(folder, "*.*", SearchOption.AllDirectories);
            var directories       = new List <string>
            {
                folder
            };

            directories.AddRange(folderDirectories);
            foreach (var directory in directories)
            {
                Console.WriteLine($"╔ ░▒▓ Inspecting [{ directory }] ▓▒░");
                Console.WriteLine("╠═╗");
                // Get all the MP3 files in the folder
                var files = Directory.GetFiles(directory, "*.mp3", SearchOption.TopDirectoryOnly);
                if (files == null || !files.Any())
                {
                    continue;
                }
                Console.WriteLine($"Found [{ files.Length }] mp3 Files");
                Console.WriteLine("╠═╣");
                // Get audiometadata and output details including weight/validity
                foreach (var file in files)
                {
                    var tagLib = this.TagsHelper.MetaDataForFile(file);
                    Console.WriteLine(tagLib.Data);
                }
                Console.WriteLine("╠═╣");
                List <AudioMetaData> fileMetaDatas = new List <AudioMetaData>();
                List <FileInfo>      fileInfos     = new List <FileInfo>();
                foreach (var file in files)
                {
                    var fileInfo     = new FileInfo(file);
                    var tagLib       = this.TagsHelper.MetaDataForFile(fileInfo.FullName);
                    var artistToken  = ArtistInspectorToken(tagLib.Data);
                    var releaseToken = ReleaseInspectorToken(tagLib.Data);
                    var newFileName  = $"{artistToken}_{releaseToken}_CD{ (tagLib.Data.Disk ?? ID3TagsHelper.DetermineDiscNumber(tagLib.Data)).ToString("000") }_{ tagLib.Data.TrackNumber.Value.ToString("0000") }.mp3";
                    var subFolder    = folder == destination ? fileInfo.DirectoryName : destination;
                    var newPath      = Path.Combine(destination, subFolder, newFileName.ToFileNameFriendly());
                    if (!doCopy)
                    {
                        if (fileInfo.FullName != newPath)
                        {
                            if (File.Exists(newPath))
                            {
                                File.Delete(newPath);
                            }
                            fileInfo.MoveTo(newPath);
                        }
                    }
                    else
                    {
                        fileInfo.CopyTo(newPath, true);
                    }
                    tagLib.Data.Filename = fileInfo.FullName;
                    fileMetaDatas.Add(tagLib.Data);
                    fileInfos.Add(fileInfo);
                }
                // Perform InspectorPlugins
                IEnumerable <AudioMetaData> pluginMetaData = fileMetaDatas.OrderBy(x => x.Filename);
                foreach (var plugin in this.Plugins.OrderBy(x => x.Order))
                {
                    Console.WriteLine($"╟ Running Plugin { plugin.Description }");
                    OperationResult <IEnumerable <AudioMetaData> > pluginResult = null;
                    try
                    {
                        pluginResult = plugin.Process(pluginMetaData);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Plugin Error: [{ ex.ToString() }]");
                    }
                    if (!pluginResult.IsSuccess)
                    {
                        Console.WriteLine($"Plugin Failed. Error [{ JsonConvert.SerializeObject(pluginResult)}]");
                    }
                    pluginMetaData = pluginResult.Data;
                }
                // Save all plugin modifications to the MetaData
                foreach (var metadata in pluginMetaData)
                {
                    this.TagsHelper.WriteTags(metadata, metadata.Filename);
                }
                Console.WriteLine("╠═╣");
                // Get audiometadata and output details including weight/validity
                foreach (var fileInfo in fileInfos)
                {
                    var tagLib = this.TagsHelper.MetaDataForFile(fileInfo.FullName);
                    if (!tagLib.IsSuccess || !tagLib.Data.IsValid)
                    {
                        Console.WriteLine($"■■ INVALID: {tagLib.Data }");
                    }
                    else
                    {
                        Console.WriteLine(tagLib.Data);
                    }
                }
                Console.WriteLine("╚═╝");
            }
        }