From 432cb6bd57f5a29a3b317f00590305d3fed9f3a9 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sun, 25 Jan 2026 16:27:49 +0900 Subject: [PATCH 1/8] Update package --- src/CCVTAC.Main/CCVTAC.Main.fsproj | 2 +- src/CCVTAC.Tests/CCVTAC.Tests.fsproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CCVTAC.Main/CCVTAC.Main.fsproj b/src/CCVTAC.Main/CCVTAC.Main.fsproj index c086ba6..d1be601 100644 --- a/src/CCVTAC.Main/CCVTAC.Main.fsproj +++ b/src/CCVTAC.Main/CCVTAC.Main.fsproj @@ -40,7 +40,7 @@ - + diff --git a/src/CCVTAC.Tests/CCVTAC.Tests.fsproj b/src/CCVTAC.Tests/CCVTAC.Tests.fsproj index 90ce196..9fa7f3d 100644 --- a/src/CCVTAC.Tests/CCVTAC.Tests.fsproj +++ b/src/CCVTAC.Tests/CCVTAC.Tests.fsproj @@ -14,7 +14,7 @@ - + From 337cc364ef902d19ed13114305c35f1a7b151fd6 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sun, 25 Jan 2026 16:28:21 +0900 Subject: [PATCH 2/8] Remove 'Error:' labels --- src/CCVTAC.Main/Downloading/Downloader.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CCVTAC.Main/Downloading/Downloader.fs b/src/CCVTAC.Main/Downloading/Downloader.fs index 30ae0c8..ba44373 100644 --- a/src/CCVTAC.Main/Downloading/Downloader.fs +++ b/src/CCVTAC.Main/Downloading/Downloader.fs @@ -95,12 +95,12 @@ module Downloader = Error <| $"The \"{format}\" format download was reported as successful, but no audio files were downloaded!" :: match result.Error with - | Some err -> [$"Error: {err}"] + | Some err -> [err] | None -> [] | Error err, true -> Error <| [$"The downloader reported failure for \"{format}\", yet audio files were unexpectedly downloaded!" - $"Error: {err}"] + err] | Error err, false -> let newErr = $"A download error was reported for the \"{format}\" format, and no audio files were downloaded. {err}" loop (List.append errors [newErr]) formats From baffc9bb6d0c11056620d06915346cd90fc79bbb Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sun, 25 Jan 2026 16:30:38 +0900 Subject: [PATCH 3/8] Use package funcs --- src/CCVTAC.Main/Downloading/Downloading.fs | 21 ++++++++------------- src/CCVTAC.Main/History.fs | 4 +--- src/CCVTAC.Main/PostProcessing/Mover.fs | 6 +++--- src/CCVTAC.Main/PostProcessing/Renamer.fs | 13 +++++++------ 4 files changed, 19 insertions(+), 25 deletions(-) diff --git a/src/CCVTAC.Main/Downloading/Downloading.fs b/src/CCVTAC.Main/Downloading/Downloading.fs index 1d8673b..f266df0 100644 --- a/src/CCVTAC.Main/Downloading/Downloading.fs +++ b/src/CCVTAC.Main/Downloading/Downloading.fs @@ -1,6 +1,6 @@ namespace CCVTAC.Main.Downloading -open System.Text.RegularExpressions +open CCFSharpUtils.Library module Downloading = @@ -17,24 +17,19 @@ module Downloading = type Urls = { Primary: PrimaryUrl Metadata: SupplementaryUrl } - let private (|RegexMatch|_|) pattern input = - match Regex.Match(input, pattern) with - | m when m.Success -> Some (List.tail [for g in m.Groups -> g.Value]) - | _ -> None - let mediaTypeWithIds url : Result = match url with - | RegexMatch @"(?<=v=|v\=)([\w-]{11})(?:&list=([\w_-]+))" [videoId; playlistId] -> + | Rgx.MatchGroups @"(?<=v=|v\=)([\w-]{11})(?:&list=([\w_-]+))" [videoId; playlistId] -> Ok (PlaylistVideo (videoId, playlistId)) - | RegexMatch @"^([\w-]{11})$" [id] - | RegexMatch @"(?<=v=|v\\=)([\w-]{11})" [id] - | RegexMatch @"(?<=youtu\.be/)(.{11})" [id] -> + | Rgx.MatchGroups @"^([\w-]{11})$" [id] + | Rgx.MatchGroups @"(?<=v=|v\\=)([\w-]{11})" [id] + | Rgx.MatchGroups @"(?<=youtu\.be/)(.{11})" [id] -> Ok (Video id) - | RegexMatch @"(?<=list=)(P[\w\-]+)" [id] -> + | Rgx.MatchGroups @"(?<=list=)(P[\w\-]+)" [id] -> Ok (StandardPlaylist id) - | RegexMatch @"(?<=list=)(O[\w\-]+)" [id] -> + | Rgx.MatchGroups @"(?<=list=)(O[\w\-]+)" [id] -> Ok (ReleasePlaylist id) - | RegexMatch @"((?:www\.)?youtube\.com\/(?:channel\/|c\/|user\/|@)(?:[A-Za-z0-9\-@%\/]+))" [id] -> + | Rgx.MatchGroups @"((?:www\.)?youtube\.com\/(?:channel\/|c\/|user\/|@)(?:[A-Za-z0-9\-@%\/]+))" [id] -> Ok (Channel id) | _ -> Error $"Unable to determine media type of URL \"{url}\". (Might it contain invalid characters?)" diff --git a/src/CCVTAC.Main/History.fs b/src/CCVTAC.Main/History.fs index 9af3e5a..25f44b2 100644 --- a/src/CCVTAC.Main/History.fs +++ b/src/CCVTAC.Main/History.fs @@ -30,9 +30,7 @@ type History(filePath: string, displayCount: int) = try let lines = File.ReadAllLines this.FilePath - |> Seq.rev - |> Seq.truncate this.DisplayCount - |> Seq.rev + |> Seq.takeLast this.DisplayCount |> Seq.toList let historyData = diff --git a/src/CCVTAC.Main/PostProcessing/Mover.fs b/src/CCVTAC.Main/PostProcessing/Mover.fs index abb3c7c..c8eedc5 100644 --- a/src/CCVTAC.Main/PostProcessing/Mover.fs +++ b/src/CCVTAC.Main/PostProcessing/Mover.fs @@ -93,8 +93,8 @@ module Mover = let private getSafeSubDirectoryName (collectionData: CollectionMetadata option) taggingSet : string = let workingName = match collectionData with - | Some metadata when String.hasText metadata.Uploader && - String.hasText metadata.Title -> metadata.Uploader + | Some metadata when String.allHaveText [metadata.Uploader; metadata.Title] -> + metadata.Uploader | _ -> match getParsedVideoJson taggingSet with | Ok v -> v.Uploader @@ -121,7 +121,7 @@ module Mover = | None -> printer.Error "No tagging sets provided" | Some firstTaggingSet -> let subFolderName = getSafeSubDirectoryName maybeCollectionData firstTaggingSet - let collectionName = maybeCollectionData |> Option.map _.Title |> Option.defaultValue String.Empty + let collectionName = maybeCollectionData |> Option.mapElse _.Title String.Empty let fullMoveToDir = Path.Combine(settings.MoveToDirectory, subFolderName, collectionName) match Directories.ensureDirectoryExists fullMoveToDir with diff --git a/src/CCVTAC.Main/PostProcessing/Renamer.fs b/src/CCVTAC.Main/PostProcessing/Renamer.fs index 0c06de5..9af82f3 100644 --- a/src/CCVTAC.Main/PostProcessing/Renamer.fs +++ b/src/CCVTAC.Main/PostProcessing/Renamer.fs @@ -24,8 +24,7 @@ module Renamer = let matches = regex.Matches(sb.ToString()) - |> Seq.cast - |> Seq.filter _.Success + |> Rgx.successMatches |> Seq.rev |> Seq.toList @@ -46,8 +45,8 @@ module Renamer = // Build replacement text by replacing % placeholders with group captures. let replacementText = - m.Groups - |> Seq.cast + m + |> Rgx.groups |> Seq.mapi (fun i _ -> let searchFor = sprintf "%%<%d>s" (i + 1) let replaceWith = @@ -56,7 +55,9 @@ module Renamer = then m.Groups[i + 1].Value.Trim() else String.Empty (searchFor, replaceWith)) - |> Seq.fold (fun (sb': StringBuilder) -> sb'.Replace) (StringBuilder renamePattern.ReplaceWithPattern) + |> Seq.fold + (fun (sb': StringBuilder) -> sb'.Replace) + (StringBuilder renamePattern.ReplaceWithPattern) |> _.ToString() sb.Insert(m.Index, replacementText) |> ignore @@ -88,7 +89,7 @@ module Renamer = try let destinationPath = Path.Combine(workingDirectory, newFileName) - |> _.Normalize(toNormalizationForm userSettings.NormalizationForm) + .Normalize(toNormalizationForm userSettings.NormalizationForm) File.Move(audioFile.FullName, destinationPath) From e2d929378e12ac004a5e93c6aa86b110a9b9a68e Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sun, 25 Jan 2026 16:33:19 +0900 Subject: [PATCH 4/8] Rework loop --- src/CCVTAC.Main/Orchestrator.fs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index 788cba1..3b04721 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -222,12 +222,14 @@ module Orchestrator = let watch = Watch() let batchResults = ResultTracker printer let mutable nextAction = NextAction.Continue - let mutable inputIndex = 0 let mutable currentSettings = settings - for input in categorizedInputs do - let mutable stop = false - inputIndex <- inputIndex + 1 + use e = (Seq.ofList categorizedInputs).GetEnumerator() + let mutable inputIndex = 1 + let mutable stop = false + + while not stop && e.MoveNext() do + let input = e.Current let result = match input.Category with @@ -249,6 +251,7 @@ module Orchestrator = | Some us -> currentSettings <- us if nextAction <> NextAction.Continue then stop <- true + inputIndex <- inputIndex + 1 if categoryCounts[InputCategory.Url] > 1 then printer.Info(sprintf "%sFinished with batch of %d URLs in %s." @@ -257,6 +260,13 @@ module Orchestrator = watch.ElapsedFriendly) batchResults.PrintBatchFailures() + if inputIndex < categorizedInputs.Length then + let unprocessedInputs = + categorizedInputs[inputIndex-1..] + |> List.map (fun x -> $"• {x.Text}") + |> String.concat String.newLine + printer.Warning($"Some inputs were not yet processed: {String.newLine}{unprocessedInputs}") + { NextAction = nextAction UpdatedSettings = Some currentSettings } @@ -288,8 +298,10 @@ module Orchestrator = let categorizedInputs = categorizeInputs splitInputs let categoryCounts = countCategories categorizedInputs summarizeInput categorizedInputs categoryCounts printer + let batchResult = processBatch categorizedInputs categoryCounts currentSettings results history printer nextAction <- batchResult.NextAction + match batchResult.UpdatedSettings with | Some s -> currentSettings <- s | None -> () From 320bae6076edaa0e2dac61fb2879be2775386053 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sun, 25 Jan 2026 16:51:16 +0900 Subject: [PATCH 5/8] Revert "Remove 'Error:' labels" This reverts commit 337cc364ef902d19ed13114305c35f1a7b151fd6. --- src/CCVTAC.Main/Downloading/Downloader.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CCVTAC.Main/Downloading/Downloader.fs b/src/CCVTAC.Main/Downloading/Downloader.fs index ba44373..30ae0c8 100644 --- a/src/CCVTAC.Main/Downloading/Downloader.fs +++ b/src/CCVTAC.Main/Downloading/Downloader.fs @@ -95,12 +95,12 @@ module Downloader = Error <| $"The \"{format}\" format download was reported as successful, but no audio files were downloaded!" :: match result.Error with - | Some err -> [err] + | Some err -> [$"Error: {err}"] | None -> [] | Error err, true -> Error <| [$"The downloader reported failure for \"{format}\", yet audio files were unexpectedly downloaded!" - err] + $"Error: {err}"] | Error err, false -> let newErr = $"A download error was reported for the \"{format}\" format, and no audio files were downloaded. {err}" loop (List.append errors [newErr]) formats From 6378abb108513216cac095aa717da44139724906 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sun, 25 Jan 2026 16:28:21 +0900 Subject: [PATCH 6/8] Remove 'Error:' labels --- src/CCVTAC.Main/Downloading/Downloader.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CCVTAC.Main/Downloading/Downloader.fs b/src/CCVTAC.Main/Downloading/Downloader.fs index 30ae0c8..ba44373 100644 --- a/src/CCVTAC.Main/Downloading/Downloader.fs +++ b/src/CCVTAC.Main/Downloading/Downloader.fs @@ -95,12 +95,12 @@ module Downloader = Error <| $"The \"{format}\" format download was reported as successful, but no audio files were downloaded!" :: match result.Error with - | Some err -> [$"Error: {err}"] + | Some err -> [err] | None -> [] | Error err, true -> Error <| [$"The downloader reported failure for \"{format}\", yet audio files were unexpectedly downloaded!" - $"Error: {err}"] + err] | Error err, false -> let newErr = $"A download error was reported for the \"{format}\" format, and no audio files were downloaded. {err}" loop (List.append errors [newErr]) formats From 2529eb113350559344b759eb17d6f345cc0f383a Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sun, 25 Jan 2026 16:59:54 +0900 Subject: [PATCH 7/8] Rename bindings --- src/CCVTAC.Main/Orchestrator.fs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index 3b04721..f0969f9 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -242,11 +242,11 @@ module Orchestrator = batchResults.RegisterResult(input.Text, result) match result with - | Error e -> - printer.Error e - | Ok r -> - nextAction <- r.NextAction - match r.UpdatedSettings with + | Error err -> + printer.Error err + | Ok result -> + nextAction <- result.NextAction + match result.UpdatedSettings with | None -> () | Some us -> currentSettings <- us if nextAction <> NextAction.Continue then From 1fe7076447e87b950668eeae12b4586929f30e1f Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Fri, 30 Jan 2026 16:19:45 +0900 Subject: [PATCH 8/8] Update CCFSharpUtils package --- src/CCVTAC.Main/CCVTAC.Main.fsproj | 2 +- src/CCVTAC.Tests/CCVTAC.Tests.fsproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CCVTAC.Main/CCVTAC.Main.fsproj b/src/CCVTAC.Main/CCVTAC.Main.fsproj index d1be601..ef0212a 100644 --- a/src/CCVTAC.Main/CCVTAC.Main.fsproj +++ b/src/CCVTAC.Main/CCVTAC.Main.fsproj @@ -40,7 +40,7 @@ - + diff --git a/src/CCVTAC.Tests/CCVTAC.Tests.fsproj b/src/CCVTAC.Tests/CCVTAC.Tests.fsproj index 9fa7f3d..48b79b1 100644 --- a/src/CCVTAC.Tests/CCVTAC.Tests.fsproj +++ b/src/CCVTAC.Tests/CCVTAC.Tests.fsproj @@ -14,7 +14,7 @@ - +