From d641ebe07ef464feda7256165faa7c40c1c683c0 Mon Sep 17 00:00:00 2001
From: CodeConscious <50596087+codeconscious@users.noreply.github.com>
Date: Mon, 9 Mar 2026 17:39:34 +0900
Subject: [PATCH 01/10] Update CCFSharpUtils and use new pluralization funcs
---
src/CCVTAC.Main/CCVTAC.Main.fsproj | 2 +-
src/CCVTAC.Main/Orchestrator.fs | 6 +++---
src/CCVTAC.Main/ResultTracker.fs | 6 +++---
src/CCVTAC.Main/Settings/Settings.fs | 9 +++++----
src/CCVTAC.Tests/CCVTAC.Tests.fsproj | 2 +-
5 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/src/CCVTAC.Main/CCVTAC.Main.fsproj b/src/CCVTAC.Main/CCVTAC.Main.fsproj
index ef0212a..4a588d2 100644
--- a/src/CCVTAC.Main/CCVTAC.Main.fsproj
+++ b/src/CCVTAC.Main/CCVTAC.Main.fsproj
@@ -40,7 +40,7 @@
-
+
diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs
index f0969f9..60e4e00 100644
--- a/src/CCVTAC.Main/Orchestrator.fs
+++ b/src/CCVTAC.Main/Orchestrator.fs
@@ -29,8 +29,8 @@ module Orchestrator =
: unit =
if List.hasMultiple categorizedInputs then
- let urlSummary = String.pluralizeWithCount "URL" "URLs" counts[InputCategory.Url]
- let cmdSummary = String.pluralizeWithCount "command" "commands" counts[InputCategory.Command]
+ let urlSummary = String.pluralizeSWithCount "URL" counts[InputCategory.Url]
+ let cmdSummary = String.pluralizeSWithCount "command" counts[InputCategory.Command]
printer.Info <|
match counts[InputCategory.Url], counts[InputCategory.Command] with
@@ -62,7 +62,7 @@ module Orchestrator =
| Ok () ->
if urlIndex > 1 then // Don't sleep for the first URL.
settings.SleepSecondsBetweenURLs
- |> String.pluralize "second" "seconds"
+ |> String.pluralizeS "second"
|> fun secondsLabel ->
sleep
(fun seconds -> $"Sleeping for {seconds} {secondsLabel}...")
diff --git a/src/CCVTAC.Main/ResultTracker.fs b/src/CCVTAC.Main/ResultTracker.fs
index ff717b2..8a7f4b5 100644
--- a/src/CCVTAC.Main/ResultTracker.fs
+++ b/src/CCVTAC.Main/ResultTracker.fs
@@ -43,15 +43,15 @@ type ResultTracker<'a>(printer: Printer) =
if Num.isZero failures.Count then
printer.Debug "No failures in batch."
else
- let failureLabel = String.pluralize "failure" "failures" failures.Count
+ let failureLabel = String.pluralizeS "failure" failures.Count
printer.Info $"%d{failures.Count} %s{failureLabel} in this batch:"
for pair in failures do
printer.Warning $"- %s{pair.Key}: %s{pair.Value}"
/// Prints the output for the current application session.
member _.PrintSessionSummary() : unit =
- let successLabel = String.pluralize "success" "successes" successCount
- let failureLabel = String.pluralize "failure" "failures" failures.Count
+ let successLabel = String.pluralizeEs "success" successCount
+ let failureLabel = String.pluralizeS "failure" failures.Count
printer.Info $"Quitting with %d{successCount} %s{successLabel} and %d{failures.Count} %s{failureLabel}."
diff --git a/src/CCVTAC.Main/Settings/Settings.fs b/src/CCVTAC.Main/Settings/Settings.fs
index e0fa905..6ded58d 100644
--- a/src/CCVTAC.Main/Settings/Settings.fs
+++ b/src/CCVTAC.Main/Settings/Settings.fs
@@ -84,7 +84,7 @@ module Settings =
| false -> "OFF"
let simplePluralize label count =
- String.pluralize label $"{label}s" count
+ String.pluralizeS label count
|> sprintf "%d %s" count
let tagDetectionPatternCount (patterns: TagDetectionPatterns) =
@@ -129,7 +129,7 @@ module Settings =
Printer.PrintTable table
- module Validation =
+ module Validation' =
open System.IO
let validate settings =
@@ -163,16 +163,17 @@ module Settings =
Ok settings
module IO =
+ open Validation'
open System.IO
open System.Text.Json
open System.Text.Unicode
open System.Text.Encodings.Web
- open Validation
let deserialize<'a> (json: string) : Result<'a, string> =
let options = JsonSerializerOptions()
options.AllowTrailingCommas <- true
options.ReadCommentHandling <- JsonCommentHandling.Skip
+ options.AllowDuplicateProperties <- false
try
match JsonSerializer.Deserialize<'a>(json, options) with
| null -> Error "Could not deserialize the settings JSON"
@@ -208,7 +209,7 @@ module Settings =
writeFile fileInfo defaultSettings
module LiveUpdating =
- open Validation
+ open Validation'
let toggleSplitChapters settings =
{ settings with SplitChapters = not settings.SplitChapters }
diff --git a/src/CCVTAC.Tests/CCVTAC.Tests.fsproj b/src/CCVTAC.Tests/CCVTAC.Tests.fsproj
index 48b79b1..6a9caa7 100644
--- a/src/CCVTAC.Tests/CCVTAC.Tests.fsproj
+++ b/src/CCVTAC.Tests/CCVTAC.Tests.fsproj
@@ -14,7 +14,7 @@
-
+
From d7239de43b0a8ce6edee2e799bfcc62e0b4e5962 Mon Sep 17 00:00:00 2001
From: CodeConscious <50596087+codeconscious@users.noreply.github.com>
Date: Mon, 16 Mar 2026 15:14:08 +0900
Subject: [PATCH 02/10] Update packages
---
src/CCVTAC.Main/CCVTAC.Main.fsproj | 4 ++--
src/CCVTAC.Tests/CCVTAC.Tests.fsproj | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/CCVTAC.Main/CCVTAC.Main.fsproj b/src/CCVTAC.Main/CCVTAC.Main.fsproj
index 4a588d2..47cdf54 100644
--- a/src/CCVTAC.Main/CCVTAC.Main.fsproj
+++ b/src/CCVTAC.Main/CCVTAC.Main.fsproj
@@ -43,9 +43,9 @@
-
+
-
+
diff --git a/src/CCVTAC.Tests/CCVTAC.Tests.fsproj b/src/CCVTAC.Tests/CCVTAC.Tests.fsproj
index 6a9caa7..6063cee 100644
--- a/src/CCVTAC.Tests/CCVTAC.Tests.fsproj
+++ b/src/CCVTAC.Tests/CCVTAC.Tests.fsproj
@@ -15,17 +15,17 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
From affa2dc4638bd6eb9aceb4b8f88ca4ad6039bf3b Mon Sep 17 00:00:00 2001
From: CodeConscious <50596087+codeconscious@users.noreply.github.com>
Date: Mon, 16 Mar 2026 16:03:35 +0900
Subject: [PATCH 03/10] Add videoIdFromMatch func
---
src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs b/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
index 90e4ca7..76f772d 100644
--- a/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
+++ b/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
@@ -24,6 +24,8 @@ module TaggingSet =
let allFiles t =
t.AudioFiles @ [t.JsonFile; t.ImageFile]
+ let videoIdFromMatch (m : Match) = m.Groups[1].Value
+
let private create v a j i =
{ VideoId = v
AudioFiles = a |> List.ofSeq
@@ -88,7 +90,7 @@ module TaggingSet =
|> List.ofSeq
|> List.choose isRelevantFile
|> List.map extractFileNameMatch
- |> List.groupBy _.Groups[1].Value // By video ID
+ |> List.groupBy videoIdFromMatch
|> List.map (extractFileNames >> createValidated)
|> List.sequenceResultA
|! List.collect id
From 2f37c699c269896ddced8c658857d488a1a21844 Mon Sep 17 00:00:00 2001
From: CodeConscious <50596087+codeconscious@users.noreply.github.com>
Date: Mon, 16 Mar 2026 18:00:59 +0900
Subject: [PATCH 04/10] Use pipe
---
src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs b/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
index 76f772d..90971e4 100644
--- a/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
+++ b/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
@@ -79,7 +79,7 @@ module TaggingSet =
let fileNamesHavingVideoIdsRegex =
Regex(@".+\[([\w_\-]{11})\](?:.*)?\.(\w+)", RegexOptions.Compiled)
- Rgx.trySuccessMatch fileNamesHavingVideoIdsRegex fileName
+ fileName |> Rgx.trySuccessMatch fileNamesHavingVideoIdsRegex
let extractFileNameMatch = Rgx.fstCapture
From 867825413e9f38e13ef152948fd68e999190c263 Mon Sep 17 00:00:00 2001
From: CodeConscious <50596087+codeconscious@users.noreply.github.com>
Date: Tue, 17 Mar 2026 20:51:18 +0900
Subject: [PATCH 05/10] Relocate videoIdFromMatch
---
src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs b/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
index 90971e4..8fba8fa 100644
--- a/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
+++ b/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
@@ -24,8 +24,6 @@ module TaggingSet =
let allFiles t =
t.AudioFiles @ [t.JsonFile; t.ImageFile]
- let videoIdFromMatch (m : Match) = m.Groups[1].Value
-
let private create v a j i =
{ VideoId = v
AudioFiles = a |> List.ofSeq
@@ -81,15 +79,17 @@ module TaggingSet =
fileName |> Rgx.trySuccessMatch fileNamesHavingVideoIdsRegex
- let extractFileNameMatch = Rgx.fstCapture
+ let fileNameFromMatch = Rgx.fstCapture
+
+ let videoIdFromMatch (m : Match) = m.Groups[1].Value
- let extractFileNames (x, matches: Match list) : 'a * string list =
- x, matches |> List.map _.Groups[0].Value
+ let extractFileNames (x, ms: Match list) : 'a * string list =
+ x, ms |> List.map _.Groups[0].Value
filePaths
|> List.ofSeq
|> List.choose isRelevantFile
- |> List.map extractFileNameMatch
+ |> List.map fileNameFromMatch
|> List.groupBy videoIdFromMatch
|> List.map (extractFileNames >> createValidated)
|> List.sequenceResultA
From b9267d4906a356153086f3c84b065aeefcdfcd94 Mon Sep 17 00:00:00 2001
From: CodeConscious <50596087+codeconscious@users.noreply.github.com>
Date: Fri, 20 Mar 2026 11:24:25 +0900
Subject: [PATCH 06/10] Update packages
---
src/CCVTAC.Main/CCVTAC.Main.fsproj | 4 ++--
src/CCVTAC.Tests/CCVTAC.Tests.fsproj | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/CCVTAC.Main/CCVTAC.Main.fsproj b/src/CCVTAC.Main/CCVTAC.Main.fsproj
index 47cdf54..9f84388 100644
--- a/src/CCVTAC.Main/CCVTAC.Main.fsproj
+++ b/src/CCVTAC.Main/CCVTAC.Main.fsproj
@@ -40,12 +40,12 @@
-
+
-
+
diff --git a/src/CCVTAC.Tests/CCVTAC.Tests.fsproj b/src/CCVTAC.Tests/CCVTAC.Tests.fsproj
index 6063cee..09bb393 100644
--- a/src/CCVTAC.Tests/CCVTAC.Tests.fsproj
+++ b/src/CCVTAC.Tests/CCVTAC.Tests.fsproj
@@ -14,18 +14,18 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
From 4cd5ddbcd8040b284d9d8e8c9eb6142ca1122fef Mon Sep 17 00:00:00 2001
From: CodeConscious <50596087+codeconscious@users.noreply.github.com>
Date: Fri, 20 Mar 2026 11:26:19 +0900
Subject: [PATCH 07/10] Use List.mapSnds, etc.
---
.../PostProcessing/Tagging/TaggingSet.fs | 22 ++++++++-----------
1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs b/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
index 8fba8fa..cc1acef 100644
--- a/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
+++ b/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
@@ -70,27 +70,23 @@ module TaggingSet =
/// Any validation errors will be accumulated and return in an Error.
let createSets filePaths : Result =
if Seq.isEmpty filePaths then
- Error ["No filepaths to create a tagging set were provided."]
+ Error ["No file paths to create a tagging set were provided."]
else
- let isRelevantFile fileName =
+ let isRelevantFile fileName : Match option =
// Regex group 0 is the full filename, and group 1 contains the video ID.
- let fileNamesHavingVideoIdsRegex =
+ let fileNamesHavingVideoIdsRgx =
Regex(@".+\[([\w_\-]{11})\](?:.*)?\.(\w+)", RegexOptions.Compiled)
- fileName |> Rgx.trySuccessMatch fileNamesHavingVideoIdsRegex
+ fileName |> Rgx.trySuccessMatch fileNamesHavingVideoIdsRgx
- let fileNameFromMatch = Rgx.fstCapture
-
- let videoIdFromMatch (m : Match) = m.Groups[1].Value
-
- let extractFileNames (x, ms: Match list) : 'a * string list =
- x, ms |> List.map _.Groups[0].Value
+ let fileName (m: Match) = m.Groups[0].Value
+ let videoId (m: Match) = m.Groups[1].Value
filePaths
|> List.ofSeq
|> List.choose isRelevantFile
- |> List.map fileNameFromMatch
- |> List.groupBy videoIdFromMatch
- |> List.map (extractFileNames >> createValidated)
+ |> List.groupBy videoId
+ |> List.map (List.mapSnds fileName)
+ |> List.map createValidated
|> List.sequenceResultA
|! List.collect id
From ca6a057f1466be731817201c7cd2d1d76bc7d054 Mon Sep 17 00:00:00 2001
From: CodeConscious <50596087+codeconscious@users.noreply.github.com>
Date: Fri, 20 Mar 2026 17:57:23 +0900
Subject: [PATCH 08/10] Update package; use new List.mapSnds
---
src/CCVTAC.Main/CCVTAC.Main.fsproj | 2 +-
src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs | 2 +-
src/CCVTAC.Tests/CCVTAC.Tests.fsproj | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/CCVTAC.Main/CCVTAC.Main.fsproj b/src/CCVTAC.Main/CCVTAC.Main.fsproj
index 9f84388..8b4440f 100644
--- a/src/CCVTAC.Main/CCVTAC.Main.fsproj
+++ b/src/CCVTAC.Main/CCVTAC.Main.fsproj
@@ -40,7 +40,7 @@
-
+
diff --git a/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs b/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
index cc1acef..5f97b48 100644
--- a/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
+++ b/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
@@ -86,7 +86,7 @@ module TaggingSet =
|> List.ofSeq
|> List.choose isRelevantFile
|> List.groupBy videoId
- |> List.map (List.mapSnds fileName)
+ |> List.mapSnds fileName
|> List.map createValidated
|> List.sequenceResultA
|! List.collect id
diff --git a/src/CCVTAC.Tests/CCVTAC.Tests.fsproj b/src/CCVTAC.Tests/CCVTAC.Tests.fsproj
index 09bb393..800c80a 100644
--- a/src/CCVTAC.Tests/CCVTAC.Tests.fsproj
+++ b/src/CCVTAC.Tests/CCVTAC.Tests.fsproj
@@ -14,7 +14,7 @@
-
+
From f4db75effba9959f73c639870dd75c2f035d3522 Mon Sep 17 00:00:00 2001
From: CodeConscious <50596087+codeconscious@users.noreply.github.com>
Date: Sat, 21 Mar 2026 18:01:14 +0900
Subject: [PATCH 09/10] Update package
---
src/CCVTAC.Main/CCVTAC.Main.fsproj | 2 +-
src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs | 4 ++--
src/CCVTAC.Tests/CCVTAC.Tests.fsproj | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/CCVTAC.Main/CCVTAC.Main.fsproj b/src/CCVTAC.Main/CCVTAC.Main.fsproj
index 8b4440f..a99b120 100644
--- a/src/CCVTAC.Main/CCVTAC.Main.fsproj
+++ b/src/CCVTAC.Main/CCVTAC.Main.fsproj
@@ -40,7 +40,7 @@
-
+
diff --git a/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs b/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
index 5f97b48..2ebad88 100644
--- a/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
+++ b/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
@@ -80,13 +80,13 @@ module TaggingSet =
fileName |> Rgx.trySuccessMatch fileNamesHavingVideoIdsRgx
let fileName (m: Match) = m.Groups[0].Value
- let videoId (m: Match) = m.Groups[1].Value
+ let videoId (m: Match) = m.Groups[1].Value
filePaths
|> List.ofSeq
|> List.choose isRelevantFile
|> List.groupBy videoId
- |> List.mapSnds fileName
+ |> List.mapSnd fileName
|> List.map createValidated
|> List.sequenceResultA
|! List.collect id
diff --git a/src/CCVTAC.Tests/CCVTAC.Tests.fsproj b/src/CCVTAC.Tests/CCVTAC.Tests.fsproj
index 800c80a..d868ec7 100644
--- a/src/CCVTAC.Tests/CCVTAC.Tests.fsproj
+++ b/src/CCVTAC.Tests/CCVTAC.Tests.fsproj
@@ -14,7 +14,7 @@
-
+
From d1faaa13912d3a008dad9a844b16aa04b1ac7ef5 Mon Sep 17 00:00:00 2001
From: CodeConscious <50596087+codeconscious@users.noreply.github.com>
Date: Sat, 21 Mar 2026 21:13:17 +0900
Subject: [PATCH 10/10] Rename binding
---
src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs b/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
index 2ebad88..100a81b 100644
--- a/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
+++ b/src/CCVTAC.Main/PostProcessing/Tagging/TaggingSet.fs
@@ -30,7 +30,7 @@ module TaggingSet =
JsonFile = j
ImageFile = i }
- let private createValidated (videoId, files) : Result =
+ let private createValidated (videoId, fileNames) : Result =
let ensureNotEmpty xs errorMsg : Validation<'a list, string> =
if List.isNotEmpty xs
then Ok xs
@@ -48,11 +48,11 @@ module TaggingSet =
| NonNull empty when String.hasNoText empty -> false
| NonNull ext -> Files.audioFileExts |> List.containsIgnoreCase ext
- let audioFiles = files |> List.filter hasSupportedAudioExt
- let jsonFiles = files |> Files.filterByExt Files.jsonFileExt
+ let audioFiles = fileNames |> List.filter hasSupportedAudioExt
+ let jsonFiles = fileNames |> Files.filterByExt Files.jsonFileExt
let imageFiles =
Files.imageFileExts
- |> List.collect (fun ext -> files |> Files.filterByExt ext)
+ |> List.collect (fun ext -> fileNames |> Files.filterByExt ext)
Validation.map3
(fun a j i -> create videoId a j i)