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 @@
-
+