Skip to content

Commit e99cd2a

Browse files
Upgrade to .NET 10 (#94)
* Upgrade projects to .NET 10 * Use extension members * Various tweaks * Various tweaks to Operations * Library project tweaks * Remove unneeded code
1 parent e9d7ede commit e99cd2a

17 files changed

Lines changed: 105 additions & 136 deletions

README.md

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Additionally, your original audio files will be modified during selected operati
88

99
## Requirements
1010

11-
- [.NET 9 runtime](https://dotnet.microsoft.com/en-us/download/dotnet/9.0)
11+
- [.NET 10 runtime](https://dotnet.microsoft.com/en-us/download/dotnet/10.0)
1212
- `settings.json` (See below)
1313

1414
## Running
@@ -36,24 +36,24 @@ dotnet run -- -r ~/Downloads/Audio/
3636

3737
## Flags
3838

39-
| Flags | Description
39+
| Flags | Description |
4040
|---|---|
41-
| -v, --view | View full tag data.
42-
| -vs, --view-summary | View a summary of tag data.
43-
| -u, --update | Update tag data using filename patterns from the settings.
44-
| -u1, --update-single | Update a single tag in multiple files to a single, manually-specified value.
45-
| -ug, --update-genres | Update the genres in all files automatically using the CSV specified in the settings.
46-
| -um, --update-multiple | Update a single tag in multiple files with multiple values.
47-
| -uy, --update-year | Update the year using media files' own dates of creation. (Must do before other updates, lest the creation date be modified by those updates.)
48-
| -urt, --reverse-track-numbers | Reverse the track numbers of the given files.
49-
| -uea, --extract-artwork | Extracts artwork from directory files if they have the same artist and album, then deletes the artwork from the files containing it.
50-
| -ura, --remove-artwork | Removes artwork from files. (File size is not reduced, as padding remains.)
51-
| -rt, --rewrite-tags | Rewrites file tags. (Can be helping in reducing padding, such as from removed artwork.)
52-
| -r, --rename | Rename and reorganize files into folders based on tag data.
53-
| -d, --duplicates | List tracks with identical artists and titles. No files are modified or deleted.
54-
| -s, --stats | Display file statistics based on tag data.
55-
| -g, --genres | Save the primary genre for each artist to a genre file.
56-
| -p, --parse | Get a single tag value by parsing the data of another (generally Comments).
41+
| -v, --view | View full tag data. |
42+
| -vs, --view-summary | View a summary of tag data. |
43+
| -u, --update | Update tag data using filename patterns from the settings. |
44+
| -u1, --update-single | Update a single tag in multiple files to a single, manually-specified value. |
45+
| -ug, --update-genres | Update the genres in all files automatically using the CSV specified in the settings. |
46+
| -um, --update-multiple | Update a single tag in multiple files with multiple values. |
47+
| -uy, --update-year | Update the year using media files' own dates of creation. (Must do before other updates, lest the creation date be modified by those updates.) |
48+
| -urt, --reverse-track-numbers | Reverse the track numbers of the given files. |
49+
| -uea, --extract-artwork | Extracts artwork from directory files if they have the same artist and album, then deletes the artwork from the files containing it. |
50+
| -ura, --remove-artwork | Removes artwork from files. (File size is not reduced, as padding remains.) |
51+
| -rt, --rewrite-tags | Rewrites file tags. (Can be helping in reducing padding, such as from removed artwork.) |
52+
| -r, --rename | Rename and reorganize files into folders based on tag data. |
53+
| -d, --duplicates | List tracks with identical artists and titles. No files are modified or deleted. |
54+
| -s, --stats | Display file statistics based on tag data. |
55+
| -g, --genres | Save the primary genre for each artist to a genre file. |
56+
| -p, --parse | Get a single tag value by parsing the data of another (generally Comments). |
5757

5858
Passing no arguments will also display these instructions.
5959

@@ -72,7 +72,7 @@ A sample settings file, which can you copy and paste if you wish, follows:
7272
"(?:(?<albumArtists>.+) ≡ )?(?<album>.+?)(?: ?\\[(?<year>\\d{4})\\])? = (?<trackNo>\\d+) [–-] (?<artists>.+?) [–-] (?<title>.+)(?=\\.(?:m4a|opus))",
7373
"(?:(?<albumArtists>.+) ≡ )?(?<album>.+?)(?: ?\\[(?<year>\\d{4})\\])? = (?<trackNo>\\d{1,3}) [–-] (?<title>.+)(?=\\.(?:m4a|opus))",
7474
"(?:(?<albumArtists>.+) ≡ )(?<album>.+?)(?: ?\\[(?<year>\\d{4})\\])? = (?<artists>.+?) [–-] (?<title>.+)(?=\\.(?:m4a|opus))",
75-
"(?:(?<albumArtists>.+) ≡ )?(?<album>.+?)(?: ?\\[(?<year>\\d{4})\\])? = (?<title>.+)(?=\\.(?:m4a|opus))", ]
75+
"(?:(?<albumArtists>.+) ≡ )?(?<album>.+?)(?: ?\\[(?<year>\\d{4})\\])? = (?<title>.+)(?=\\.(?:m4a|opus))" ]
7676
},
7777
"renaming": {
7878
"useAlbumDirectories": true,
@@ -99,7 +99,7 @@ A sample settings file, which can you copy and paste if you wish, follows:
9999
"exclusions": [
100100
{ "artist": "Artist Name" },
101101
{ "title": "Track Title" },
102-
{ "artist": "Artist Name", "title": "Track Title" },
102+
{ "artist": "Artist Name", "title": "Track Title" }
103103
],
104104
"artistReplacements": [
105105
" ",
@@ -131,7 +131,7 @@ A sample settings file, which can you copy and paste if you wish, follows:
131131
":",
132132
""
133133
]
134-
},
134+
}
135135
}
136136
```
137137

src/AudioTagger.Console/AudioTagger.Console.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<OutputType>Exe</OutputType>
4-
<TargetFramework>net9.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<ImplicitUsings>disable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
<AssemblyName>Audiotagger.Console</AssemblyName>
@@ -30,4 +30,4 @@
3030
<ItemGroup>
3131
<ProjectReference Include="..\AudioTagger.Library\AudioTagger.Library.csproj"/>
3232
</ItemGroup>
33-
</Project>
33+
</Project>

src/AudioTagger.Console/Extensions.cs

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,24 @@ namespace AudioTagger.Console;
22

33
public static class Extensions
44
{
5-
/// <summary>
6-
/// Determines whether a collection is empty.
7-
/// </summary>
8-
public static bool None<T>(this IEnumerable<T> collection) =>
9-
!collection.Any();
5+
extension<T>(IEnumerable<T> collection)
6+
{
7+
public bool None() =>
8+
!collection.Any();
109

11-
/// <summary>
12-
/// Determines whether no elements of a sequence satisfy a given condition.
13-
/// </summary>
14-
public static bool None<T>(this IEnumerable<T> collection, Func<T, bool> predicate) =>
15-
!collection.Any(predicate);
10+
public bool None(Func<T, bool> predicate) =>
11+
!collection.Any(predicate);
12+
}
1613

17-
/// <summary>
18-
/// Returns a bool indicating whether a string is not null and has text (true) or not.
19-
/// </summary>
20-
public static bool HasText(this string? str) => !string.IsNullOrWhiteSpace(str);
14+
extension(string? str)
15+
{
16+
public bool HasText() => !string.IsNullOrWhiteSpace(str);
2117

22-
public static string? TextOrNull(this string? text) =>
23-
text switch
24-
{
25-
null or { Length: 0 } => null,
26-
_ => text
27-
};
18+
public string? TextOrNull() =>
19+
str switch
20+
{
21+
null or { Length: 0 } => null,
22+
_ => str
23+
};
24+
}
2825
}

src/AudioTagger.Console/GetUserInput.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ public static class ResponseHandler
2626
/// <summary>
2727
/// Ask the user a question that they can answer with a single keystroke.
2828
/// </summary>
29-
private static UserResponse AskUserQuestion(IReadOnlyList<LineSubString> question,
30-
IReadOnlyList<KeyResponse> allowedResponses,
31-
IPrinter printer)
29+
private static UserResponse AskUserQuestion(
30+
IReadOnlyList<LineSubString> question,
31+
IReadOnlyList<KeyResponse> allowedResponses,
32+
IPrinter printer)
3233
{
3334
if (question.None())
3435
{

src/AudioTagger.Console/MediaFilePathInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
namespace AudioTagger.Console;
22

33
/// <summary>
4-
/// Contains all of the path information for a specific MediaFile.
4+
/// Contains all the path information for a specific MediaFile.
55
/// </summary>
66
internal sealed class MediaFilePathInfo
77
{

src/AudioTagger.Console/MediaFileViewer.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace AudioTagger.Console;
55

66
public sealed class MediaFileViewer
77
{
8-
public void PrintFileDetails(MediaFile file)
8+
public static void PrintFileDetails(MediaFile file)
99
{
1010
// TODO: Handle colors more gracefully.
1111
string TagNameFormatter(string s) => "[grey]" + s + "[/]";
@@ -30,7 +30,7 @@ public void PrintFileDetails(MediaFile file)
3030
table.AddRow(TagNameFormatter("Year"), file.Year.ToString());
3131
table.AddRow(TagNameFormatter("Duration"), file.Duration.ToString("m\\:ss"));
3232

33-
int genreCount = file.Genres.Length;
33+
var genreCount = file.Genres.Length;
3434
table.AddRow(TagNameFormatter("Genres"),
3535
file.Genres.Join().EscapeMarkup() +
3636
(genreCount > 1 ? $" ({genreCount})" : string.Empty));
@@ -82,7 +82,7 @@ public static TableRow PrintFileSummary(MediaFile file)
8282
file.ReplayGainTrack.ToString(CultureInfo.InvariantCulture)
8383
};
8484

85-
IEnumerable<Markup> markups = rows.Select(r => new Markup(r));
85+
var markups = rows.Select(r => new Markup(r));
8686

8787
return new TableRow(markups);
8888
}

src/AudioTagger.Console/Operations/MediaFileRenamer.cs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -281,20 +281,15 @@ private static bool RenameSingleFile(
281281

282282
return shouldCancel;
283283

284-
/// <summary>
285-
/// Generates and returns a new filename by replacing placeholders within the rename
286-
/// pattern (e.g., `%ALBUM%`) with actual tag data from the `MediaFile`.
287-
/// </summary>
284+
// Generates and returns a new filename by replacing placeholders within the rename
285+
// pattern (e.g., `%ALBUM%`) with actual tag data from the `MediaFile`.
288286
static string GenerateFileName(
289287
MediaFile file,
290288
ICollection<string> fileTagNames,
291289
string renamePattern)
292290
{
293291
StringBuilder workingFileName =
294-
fileTagNames.Aggregate(
295-
new StringBuilder(renamePattern),
296-
(workingName, tagName) => ReplacePlaceholders(workingName, tagName)
297-
);
292+
fileTagNames.Aggregate(new StringBuilder(renamePattern), ReplacePlaceholders);
298293

299294
var ext = Path.GetExtension(file.FileNameOnly);
300295
var unsanitizedName = workingFileName + ext;
@@ -333,9 +328,7 @@ StringBuilder ReplacePlaceholders(StringBuilder workingName, string tagName)
333328
}
334329
}
335330

336-
/// <summary>
337-
/// Generates and returns a directory name for a file given its tags. Never returns null.
338-
/// </summary>
331+
// Generates and returns a directory name for a file given its tags. Never returns null.
339332
static string GenerateSafeDirectoryName(MediaFile file)
340333
{
341334
if (MediaFile.HasAnyValues(file.AlbumArtists))

src/AudioTagger.Console/Operations/TagDuplicateFinder.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public void Start(
3939
string artistLabel = PluralizeTerm(artistReplacements.Count);
4040
printer.Print($"Found {artistReplacements.Count} artist replacement {artistLabel}.");
4141

42-
var titleReplacements = settings.Duplicates?.TitleReplacements ?? [];
42+
var titleReplacements = settings.Duplicates.TitleReplacements ?? [];
4343
string titleLabel = PluralizeTerm(titleReplacements.Count);
4444
printer.Print($"Found {titleReplacements.Count} title replacement {titleLabel}.");
4545

@@ -64,9 +64,9 @@ public void Start(
6464
printer.Print($"Found {groupCount} duplicate {groupLabel} in {watch.ElapsedFriendly}.");
6565
PrintResults(duplicateGroups, printer);
6666

67-
string? searchFor = settings.Duplicates?.PathSearchFor?.TextOrNull();
68-
string? replaceWith = settings.Duplicates?.PathReplaceWith?.TextOrNull();
69-
string? saveDir = settings?.Duplicates?.SavePlaylistDirectory;
67+
string? searchFor = settings.Duplicates.PathSearchFor?.TextOrNull();
68+
string? replaceWith = settings.Duplicates.PathReplaceWith?.TextOrNull();
69+
string? saveDir = settings.Duplicates.SavePlaylistDirectory;
7070
CreatePlaylistFile(duplicateGroups, saveDir, (searchFor, replaceWith), printer);
7171
}
7272

src/AudioTagger.Console/Operations/TagUpdater.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ private static bool UpdateTags(
7777
return shouldCancel;
7878
}
7979

80-
IEnumerable<Group>? matchedTags = match.Groups
80+
IEnumerable<Group> matchedTags = match.Groups
8181
.OfType<Group>()
8282
.Where(g => g.Success);
8383

84-
if (matchedTags.Any() != true)
84+
if (!matchedTags.Any())
8585
{
8686
printer.Print($"Could not parse data for filename \"{mediaFile.FileNameOnly}.\"",
8787
ResultType.Failure);

src/AudioTagger.Console/Operations/TagUpdaterMultiple.cs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ private static void UpdateTags(MediaFile mediaFile,
175175
string sanitizedTitle = tagValue.Trim().Normalize()
176176
.Replace("___", " ")
177177
.Replace("__", " ");
178-
mediaFile.Title = GetUpdatedValue(mediaFile.Title,
178+
mediaFile.Title = GetUpdatedTagValue(mediaFile.Title,
179179
sanitizedTitle,
180180
updateType,
181181
false);
@@ -208,7 +208,7 @@ private static void UpdateTags(MediaFile mediaFile,
208208
string sanitizedAlbum = tagValue.Trim().Normalize()
209209
.Replace("___", " ")
210210
.Replace("__", " ");
211-
mediaFile.Album = GetUpdatedValue(mediaFile.Album,
211+
mediaFile.Album = GetUpdatedTagValue(mediaFile.Album,
212212
sanitizedAlbum,
213213
updateType,
214214
false);
@@ -231,23 +231,15 @@ private static void UpdateTags(MediaFile mediaFile,
231231
mediaFile.TrackNo = ushort.Parse(tagValue);
232232
break;
233233
case "comment":
234-
mediaFile.Comments = GetUpdatedValue(mediaFile.Comments, tagValue, updateType, true);
234+
mediaFile.Comments = GetUpdatedTagValue(mediaFile.Comments, tagValue, updateType, true);
235235
break;
236236
default:
237237
throw new InvalidOperationException($"Unsupported tag \"{tagName}\" could not be processed.");
238238
}
239239

240240
mediaFile.SaveUpdates();
241241

242-
/// <summary>
243-
/// Returns the new, updated value for a tag.
244-
/// </summary>
245-
/// <param name="currentValue">The original value to be modified.</param>
246-
/// <param name="newValue">The text to be added.</param>
247-
/// <param name="updateType"></param>
248-
/// <param name="useNewLine">Whether or not to add line breaks between the new and old text.</param>
249-
/// <returns></returns>
250-
static string GetUpdatedValue(string currentValue, string newValue, TagUpdateType updateType, bool useNewLines)
242+
static string GetUpdatedTagValue(string currentValue, string newValue, TagUpdateType updateType, bool useNewLines)
251243
{
252244
string divider = useNewLines ? Environment.NewLine + Environment.NewLine : string.Empty;
253245
return updateType switch

0 commit comments

Comments
 (0)