From ea4b47fbe5db5ee62b5a18aaa471c5a161704bae Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sun, 2 Feb 2025 17:09:08 +0900 Subject: [PATCH 01/12] Add LastWriteTime to cached data --- src/AudioTagger.Console/OperationLibrary.cs | 10 +++---- .../Operations/TagCacher.cs | 27 ++++++++++--------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/AudioTagger.Console/OperationLibrary.cs b/src/AudioTagger.Console/OperationLibrary.cs index 7e21d68..ace2c85 100644 --- a/src/AudioTagger.Console/OperationLibrary.cs +++ b/src/AudioTagger.Console/OperationLibrary.cs @@ -86,15 +86,15 @@ internal static class OperationLibrary ["-p", "--parse"], "Get a single tag value by parsing the data of another (generally Comments).", new TagParser()), + new( + ["--cache-tags"], + "Cache files' tag data to a local JSON file whose path is specified in the settings.", + new TagCacher(), + isHidden: true), new( ["--scan"], "Ad-hoc maintenance scanning work. (Not intended for normal use.)", new TagScanner(), - isHidden: true), - new( - ["--cache-tags"], - "Cache files' tag data locally to a JSON file whose path is specified in the settings. (Eventually, this will be helpful in speeding up certain operations.)", - new TagCacher(), isHidden: true) ]; diff --git a/src/AudioTagger.Console/Operations/TagCacher.cs b/src/AudioTagger.Console/Operations/TagCacher.cs index d68d52a..cbe6fc0 100644 --- a/src/AudioTagger.Console/Operations/TagCacher.cs +++ b/src/AudioTagger.Console/Operations/TagCacher.cs @@ -14,7 +14,8 @@ private record TagSummary( string Title, uint Year, string[] Genres, - TimeSpan Duration + TimeSpan Duration, + DateTime UpdatedAt ); public void Start( @@ -25,23 +26,23 @@ public void Start( { if (settings.TagCacheFilePath is null) { - printer.Error("You must specify the save file path in the settings file."); + printer.Error("You must specify the save file path in the settings."); return; } Watch watch = new(); - var summaries = mediaFiles.Select(m => { - return new TagSummary( - m.Artists, - m.Album, - m.TrackNo, - m.Title, - m.Year, - m.Genres, - m.Duration - ); - }); + var summaries = + mediaFiles.Select(m => new TagSummary( + m.Artists, + m.Album, + m.TrackNo, + m.Title, + m.Year, + m.Genres, + m.Duration, + m.FileInfo.LastWriteTime + )); printer.Print("Serializing the tags to JSON..."); JsonSerializerOptions options = new() From 7ef3c18c037f6916aad066c7ae68f646dd23e1fb Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sun, 2 Feb 2025 17:11:13 +0900 Subject: [PATCH 02/12] Add album artists --- src/AudioTagger.Console/Operations/TagCacher.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/AudioTagger.Console/Operations/TagCacher.cs b/src/AudioTagger.Console/Operations/TagCacher.cs index cbe6fc0..1ff15a8 100644 --- a/src/AudioTagger.Console/Operations/TagCacher.cs +++ b/src/AudioTagger.Console/Operations/TagCacher.cs @@ -9,6 +9,7 @@ public sealed class TagCacher : IPathOperation { private record TagSummary( string[] Artists, + string[] AlbumArtists, string Album, uint TrackNo, string Title, @@ -35,6 +36,7 @@ public void Start( var summaries = mediaFiles.Select(m => new TagSummary( m.Artists, + m.AlbumArtists, m.Album, m.TrackNo, m.Title, From 27a3f1b4da32fff61d792d80bd42b4db76cbef23 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sun, 2 Feb 2025 17:19:57 +0900 Subject: [PATCH 03/12] Add IMediaData interface --- .../MediaFiles/IMediaData.cs | 22 +++++++++++++++++++ .../MediaFiles/MediaFile.cs | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/AudioTagger.Library/MediaFiles/IMediaData.cs diff --git a/src/AudioTagger.Library/MediaFiles/IMediaData.cs b/src/AudioTagger.Library/MediaFiles/IMediaData.cs new file mode 100644 index 0000000..cc2bda5 --- /dev/null +++ b/src/AudioTagger.Library/MediaFiles/IMediaData.cs @@ -0,0 +1,22 @@ +namespace AudioTagger.Library.MediaFiles; + +public interface IMediaData +{ + public string Title { get; set; } + public string[] AlbumArtists { get; set; } + public string[] Artists { get; set; } + public string Album { get; set; } + public uint Year { get; set; } + public uint TrackNo { get; set; } + public TimeSpan Duration { get; } + public string[] Genres { get; set; } + public string[] Composers { get; set; } + public string Lyrics { get; set; } + public string Comments { get; set; } + public string Description { get; set; } + public int BitRate { get; } + public int SampleRate { get; } + public double ReplayGainTrack { get; } + public double ReplayGainAlbum { get; } + public byte[] AlbumArt { get; } +} diff --git a/src/AudioTagger.Library/MediaFiles/MediaFile.cs b/src/AudioTagger.Library/MediaFiles/MediaFile.cs index 13aa141..d9c57d4 100644 --- a/src/AudioTagger.Library/MediaFiles/MediaFile.cs +++ b/src/AudioTagger.Library/MediaFiles/MediaFile.cs @@ -4,7 +4,7 @@ namespace AudioTagger.Library.MediaFiles; -public sealed class MediaFile +public sealed class MediaFile : IMediaData { public FileInfo FileInfo { get; } private TagLib.File _taggedFile; From 18b0d82853b573a10fee25462ef4116f02b2f33c Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sun, 2 Feb 2025 17:24:54 +0900 Subject: [PATCH 04/12] Add TagSummary class --- .../MediaFiles/TagSummary.cs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/AudioTagger.Library/MediaFiles/TagSummary.cs diff --git a/src/AudioTagger.Library/MediaFiles/TagSummary.cs b/src/AudioTagger.Library/MediaFiles/TagSummary.cs new file mode 100644 index 0000000..4d6c05e --- /dev/null +++ b/src/AudioTagger.Library/MediaFiles/TagSummary.cs @@ -0,0 +1,22 @@ +namespace AudioTagger.Library.MediaFiles; + +public class TagSummary : IMediaData +{ + public string Title { get; } + public string[] AlbumArtists { get; } + public string[] Artists { get; } + public string Album { get; } + public uint Year { get; } + public uint TrackNo { get; } + public TimeSpan Duration { get; } + public string[] Genres { get; } + public string[] Composers { get; } + public string Lyrics { get; } + public string Comments { get; } + public string Description { get; } + public int BitRate { get; } + public int SampleRate { get; } + public double ReplayGainTrack { get; } + public double ReplayGainAlbum { get; } + public byte[] AlbumArt { get; } +} From a19ecd9a3f7bfd71e74473ce2df52e21393deefa Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sun, 2 Feb 2025 17:25:05 +0900 Subject: [PATCH 05/12] Remove setters from interface --- .../MediaFiles/IMediaData.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/AudioTagger.Library/MediaFiles/IMediaData.cs b/src/AudioTagger.Library/MediaFiles/IMediaData.cs index cc2bda5..a59d182 100644 --- a/src/AudioTagger.Library/MediaFiles/IMediaData.cs +++ b/src/AudioTagger.Library/MediaFiles/IMediaData.cs @@ -2,18 +2,18 @@ namespace AudioTagger.Library.MediaFiles; public interface IMediaData { - public string Title { get; set; } - public string[] AlbumArtists { get; set; } - public string[] Artists { get; set; } - public string Album { get; set; } - public uint Year { get; set; } - public uint TrackNo { get; set; } + public string Title { get; } + public string[] AlbumArtists { get; } + public string[] Artists { get; } + public string Album { get; } + public uint Year { get; } + public uint TrackNo { get; } public TimeSpan Duration { get; } - public string[] Genres { get; set; } - public string[] Composers { get; set; } - public string Lyrics { get; set; } - public string Comments { get; set; } - public string Description { get; set; } + public string[] Genres { get; } + public string[] Composers { get; } + public string Lyrics { get; } + public string Comments { get; } + public string Description { get; } public int BitRate { get; } public int SampleRate { get; } public double ReplayGainTrack { get; } From 1c35f5a9c322d3fb55d322ed013545f0ffd24583 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Fri, 7 Feb 2025 16:19:59 +0900 Subject: [PATCH 06/12] Add default value to TagSummary members --- .../MediaFiles/TagSummary.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/AudioTagger.Library/MediaFiles/TagSummary.cs b/src/AudioTagger.Library/MediaFiles/TagSummary.cs index 4d6c05e..b02a73d 100644 --- a/src/AudioTagger.Library/MediaFiles/TagSummary.cs +++ b/src/AudioTagger.Library/MediaFiles/TagSummary.cs @@ -2,21 +2,21 @@ namespace AudioTagger.Library.MediaFiles; public class TagSummary : IMediaData { - public string Title { get; } - public string[] AlbumArtists { get; } - public string[] Artists { get; } - public string Album { get; } + public string Title { get; } = string.Empty; + public string[] AlbumArtists { get; } = []; + public string[] Artists { get; } = []; + public string Album { get; } = string.Empty; public uint Year { get; } public uint TrackNo { get; } public TimeSpan Duration { get; } - public string[] Genres { get; } - public string[] Composers { get; } - public string Lyrics { get; } - public string Comments { get; } - public string Description { get; } + public string[] Genres { get; } = []; + public string[] Composers { get; } = []; + public string Lyrics { get; } = string.Empty; + public string Comments { get; } = string.Empty; + public string Description { get; } = string.Empty; public int BitRate { get; } public int SampleRate { get; } public double ReplayGainTrack { get; } public double ReplayGainAlbum { get; } - public byte[] AlbumArt { get; } + public byte[] AlbumArt { get; } = []; } From a2c21854506943f6b1a920ada1039151d30a1d45 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 19 Apr 2025 11:00:53 +0900 Subject: [PATCH 07/12] Don't unescape JSON (as it causes errors for me in another tool) --- src/AudioTagger.Console/Operations/TagCacher.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/AudioTagger.Console/Operations/TagCacher.cs b/src/AudioTagger.Console/Operations/TagCacher.cs index 1ff15a8..734b014 100644 --- a/src/AudioTagger.Console/Operations/TagCacher.cs +++ b/src/AudioTagger.Console/Operations/TagCacher.cs @@ -5,7 +5,7 @@ namespace AudioTagger.Console.Operations; -public sealed class TagCacher : IPathOperation +public sealed class TagCacher { private record TagSummary( string[] Artists, @@ -53,10 +53,10 @@ public void Start( Encoder = JavaScriptEncoder.Create(UnicodeRanges.All) }; var json = JsonSerializer.Serialize(summaries, options); - var unescapedJson = System.Text.RegularExpressions.Regex.Unescape(json); // Avoids `\0027`, etc. + // var unescapedJson = System.Text.RegularExpressions.Regex.Unescape(json); // Avoids `\0027`, etc. printer.Print($"Saving cached tag data to \"{settings.TagCacheFilePath}\"..."); - File.WriteAllText(settings.TagCacheFilePath, unescapedJson); + File.WriteAllText(settings.TagCacheFilePath, json); printer.Print($"Saved in {watch.ElapsedFriendly}."); } } From ad681648f702e83eb585439ecf1ead6d6a98553f Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 19 Apr 2025 11:04:28 +0900 Subject: [PATCH 08/12] Remove IMediaFile; etc. --- src/AudioTagger.Console/OperationLibrary.cs | 3 +-- .../Operations/TagCacher.cs | 2 +- .../MediaFiles/IMediaData.cs | 22 ------------------- .../MediaFiles/MediaFile.cs | 2 +- .../MediaFiles/TagSummary.cs | 22 ------------------- 5 files changed, 3 insertions(+), 48 deletions(-) delete mode 100644 src/AudioTagger.Library/MediaFiles/IMediaData.cs delete mode 100644 src/AudioTagger.Library/MediaFiles/TagSummary.cs diff --git a/src/AudioTagger.Console/OperationLibrary.cs b/src/AudioTagger.Console/OperationLibrary.cs index ace2c85..54e28c3 100644 --- a/src/AudioTagger.Console/OperationLibrary.cs +++ b/src/AudioTagger.Console/OperationLibrary.cs @@ -89,8 +89,7 @@ internal static class OperationLibrary new( ["--cache-tags"], "Cache files' tag data to a local JSON file whose path is specified in the settings.", - new TagCacher(), - isHidden: true), + new TagCacher()), new( ["--scan"], "Ad-hoc maintenance scanning work. (Not intended for normal use.)", diff --git a/src/AudioTagger.Console/Operations/TagCacher.cs b/src/AudioTagger.Console/Operations/TagCacher.cs index 734b014..e1258c9 100644 --- a/src/AudioTagger.Console/Operations/TagCacher.cs +++ b/src/AudioTagger.Console/Operations/TagCacher.cs @@ -5,7 +5,7 @@ namespace AudioTagger.Console.Operations; -public sealed class TagCacher +public sealed class TagCacher : IPathOperation { private record TagSummary( string[] Artists, diff --git a/src/AudioTagger.Library/MediaFiles/IMediaData.cs b/src/AudioTagger.Library/MediaFiles/IMediaData.cs deleted file mode 100644 index a59d182..0000000 --- a/src/AudioTagger.Library/MediaFiles/IMediaData.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace AudioTagger.Library.MediaFiles; - -public interface IMediaData -{ - public string Title { get; } - public string[] AlbumArtists { get; } - public string[] Artists { get; } - public string Album { get; } - public uint Year { get; } - public uint TrackNo { get; } - public TimeSpan Duration { get; } - public string[] Genres { get; } - public string[] Composers { get; } - public string Lyrics { get; } - public string Comments { get; } - public string Description { get; } - public int BitRate { get; } - public int SampleRate { get; } - public double ReplayGainTrack { get; } - public double ReplayGainAlbum { get; } - public byte[] AlbumArt { get; } -} diff --git a/src/AudioTagger.Library/MediaFiles/MediaFile.cs b/src/AudioTagger.Library/MediaFiles/MediaFile.cs index d9c57d4..13aa141 100644 --- a/src/AudioTagger.Library/MediaFiles/MediaFile.cs +++ b/src/AudioTagger.Library/MediaFiles/MediaFile.cs @@ -4,7 +4,7 @@ namespace AudioTagger.Library.MediaFiles; -public sealed class MediaFile : IMediaData +public sealed class MediaFile { public FileInfo FileInfo { get; } private TagLib.File _taggedFile; diff --git a/src/AudioTagger.Library/MediaFiles/TagSummary.cs b/src/AudioTagger.Library/MediaFiles/TagSummary.cs deleted file mode 100644 index b02a73d..0000000 --- a/src/AudioTagger.Library/MediaFiles/TagSummary.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace AudioTagger.Library.MediaFiles; - -public class TagSummary : IMediaData -{ - public string Title { get; } = string.Empty; - public string[] AlbumArtists { get; } = []; - public string[] Artists { get; } = []; - public string Album { get; } = string.Empty; - public uint Year { get; } - public uint TrackNo { get; } - public TimeSpan Duration { get; } - public string[] Genres { get; } = []; - public string[] Composers { get; } = []; - public string Lyrics { get; } = string.Empty; - public string Comments { get; } = string.Empty; - public string Description { get; } = string.Empty; - public int BitRate { get; } - public int SampleRate { get; } - public double ReplayGainTrack { get; } - public double ReplayGainAlbum { get; } - public byte[] AlbumArt { get; } = []; -} From d7319321aa95fa2aa077edaf585a07eca1522491 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 19 Apr 2025 11:29:37 +0900 Subject: [PATCH 09/12] Remove TagSummary record type; add path info to JSON --- .../Operations/TagCacher.cs | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/AudioTagger.Console/Operations/TagCacher.cs b/src/AudioTagger.Console/Operations/TagCacher.cs index e1258c9..cdafa08 100644 --- a/src/AudioTagger.Console/Operations/TagCacher.cs +++ b/src/AudioTagger.Console/Operations/TagCacher.cs @@ -7,18 +7,6 @@ namespace AudioTagger.Console.Operations; public sealed class TagCacher : IPathOperation { - private record TagSummary( - string[] Artists, - string[] AlbumArtists, - string Album, - uint TrackNo, - string Title, - uint Year, - string[] Genres, - TimeSpan Duration, - DateTime UpdatedAt - ); - public void Start( IReadOnlyCollection mediaFiles, DirectoryInfo workingDirectory, @@ -34,7 +22,10 @@ public void Start( Watch watch = new(); var summaries = - mediaFiles.Select(m => new TagSummary( + mediaFiles.Select(m => new + { + m.FileNameOnly, + m.FileInfo.DirectoryName, m.Artists, m.AlbumArtists, m.Album, @@ -43,8 +34,8 @@ public void Start( m.Year, m.Genres, m.Duration, - m.FileInfo.LastWriteTime - )); + m.FileInfo.LastWriteTime, + }); printer.Print("Serializing the tags to JSON..."); JsonSerializerOptions options = new() From 4220d7134d69a3fffc7a3886975d45502ba13235 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Wed, 11 Jun 2025 17:58:42 +0900 Subject: [PATCH 10/12] Move title to top of the confirm-tag dialog --- src/AudioTagger.Library/UpdatableFields.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/AudioTagger.Library/UpdatableFields.cs b/src/AudioTagger.Library/UpdatableFields.cs index 96838fd..856aee0 100644 --- a/src/AudioTagger.Library/UpdatableFields.cs +++ b/src/AudioTagger.Library/UpdatableFields.cs @@ -131,6 +131,11 @@ public Dictionary GetUpdateKeyValuePairs(MediaFile fileData) { var updateOutput = new Dictionary(); + if (Title != null && Title != fileData.Title) + { + updateOutput.Add("Title", Title); + } + if (AlbumArtists?.All(a => fileData.AlbumArtists.Contains(a)) == false) { updateOutput.Add("Album Artists", string.Join("; ", AlbumArtists)); @@ -141,11 +146,6 @@ public Dictionary GetUpdateKeyValuePairs(MediaFile fileData) updateOutput.Add("Artists", string.Join("; ", Artists)); } - if (Title != null && Title != fileData.Title) - { - updateOutput.Add("Title", Title); - } - if (Album != null && Album != fileData.Album) { updateOutput.Add("Album", Album); From a98f4746e18098e718a5f431baea61633890e180 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Wed, 11 Jun 2025 17:59:17 +0900 Subject: [PATCH 11/12] Fix text --- src/AudioTagger.Console/Operations/TagCacher.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AudioTagger.Console/Operations/TagCacher.cs b/src/AudioTagger.Console/Operations/TagCacher.cs index cdafa08..7b524dc 100644 --- a/src/AudioTagger.Console/Operations/TagCacher.cs +++ b/src/AudioTagger.Console/Operations/TagCacher.cs @@ -37,7 +37,7 @@ public void Start( m.FileInfo.LastWriteTime, }); - printer.Print("Serializing the tags to JSON..."); + printer.Print("Serializing tag data to JSON..."); JsonSerializerOptions options = new() { WriteIndented = true, From 5e4f872603ab98c402b36079b0b5f36e1854a346 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Wed, 11 Jun 2025 18:03:37 +0900 Subject: [PATCH 12/12] Remove comment --- src/AudioTagger.Console/Operations/TagCacher.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/AudioTagger.Console/Operations/TagCacher.cs b/src/AudioTagger.Console/Operations/TagCacher.cs index 7b524dc..5fbdbdf 100644 --- a/src/AudioTagger.Console/Operations/TagCacher.cs +++ b/src/AudioTagger.Console/Operations/TagCacher.cs @@ -44,7 +44,6 @@ public void Start( Encoder = JavaScriptEncoder.Create(UnicodeRanges.All) }; var json = JsonSerializer.Serialize(summaries, options); - // var unescapedJson = System.Text.RegularExpressions.Regex.Unescape(json); // Avoids `\0027`, etc. printer.Print($"Saving cached tag data to \"{settings.TagCacheFilePath}\"..."); File.WriteAllText(settings.TagCacheFilePath, json);