From 3ca20b9b9ca3fbafc909e83b262da7deccb65980 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 15 Aug 2026 10:34:59 +0900 Subject: [PATCH 01/30] Add EmptyLines method to Printer --- src/CCVTAC.Main/Downloading/Updater.fs | 12 +++++------- src/CCVTAC.Main/Printer.fs | 11 +++++++---- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/CCVTAC.Main/Downloading/Updater.fs b/src/CCVTAC.Main/Downloading/Updater.fs index 3d937e6..976c677 100644 --- a/src/CCVTAC.Main/Downloading/Updater.fs +++ b/src/CCVTAC.Main/Downloading/Updater.fs @@ -9,22 +9,20 @@ module Updater = let run userSettings (printer: Printer) : Result = if String.hasNoText userSettings.DownloaderUpdateCommand then - printer.Info("No downloader update command provided, so will skip.") - Ok() + printer.Info "No downloader update command provided, so will skip." + Ok () else let toolSettings = ToolSettings.create userSettings.DownloaderUpdateCommand userSettings.WorkingDirectory match Runner.runTool toolSettings [] printer with | Ok result -> if result.ExitCode <> 0 then - printer.Warning("Tool updated with minor issues.") - + printer.Warning "Tool updated with minor issues." match result.Error with | Some w -> printer.Warning w | None -> () - - Ok() - + printer.EmptyLines 1uy + Ok () | Error err -> printer.Error $"Failure updating: {err}" Error err diff --git a/src/CCVTAC.Main/Printer.fs b/src/CCVTAC.Main/Printer.fs index bbe820d..e329383 100644 --- a/src/CCVTAC.Main/Printer.fs +++ b/src/CCVTAC.Main/Printer.fs @@ -136,15 +136,18 @@ type Printer(showDebug: bool) = this.Print(Level.Debug, message, ?appendLineBreak = appendLineBreak, ?prependLines = prependLines, ?appendLines = appendLines, ?processMarkup = processMarkup) + member this.EmptyLines(count: byte) = Printer.EmptyLines count + /// Prints the requested number of blank lines. static member EmptyLines(count: byte) = - if Num.isZero count - then () - else + if Num.isPos count + then let repeats = int count - 1 if repeats < 1 then AnsiConsole.WriteLine() - else Enumerable.Repeat(String.newLine, repeats) |> String.Concat |> AnsiConsole.WriteLine + else Enumerable.Repeat(String.newLine, repeats) + |> String.Concat + |> AnsiConsole.WriteLine member this.GetInput(prompt: string) : string = Printer.EmptyLines 1uy From edaf3f55196e2836cd884c9f68ab666a39d468c1 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 15 Aug 2026 10:35:45 +0900 Subject: [PATCH 02/30] Remove superfluous type names --- src/CCVTAC.Main/Orchestrator.fs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index 27470a9..010b84e 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -115,47 +115,47 @@ module Orchestrator = // Help if String.equalIgnoreCase Commands.helpCommand command then for kvp in Commands.summary do - printer.Info(kvp.Key) + printer.Info kvp.Key printer.Info $" %s{kvp.Value}" - Ok { NextAction = NextAction.Continue; UpdatedSettings = None } + Ok { NextAction = Continue; UpdatedSettings = None } // Quit elif checkCommand Commands.quitCommands then - Ok { NextAction = NextAction.QuitAtUserRequest; UpdatedSettings = None } + Ok { NextAction = QuitAtUserRequest; UpdatedSettings = None } // History elif checkCommand Commands.history then history.ShowRecent printer - Ok { NextAction = NextAction.Continue; UpdatedSettings = None } + Ok { NextAction = Continue; UpdatedSettings = None } // Update downloader elif checkCommand Commands.updateDownloader then Updater.run settings printer |> ignore - Ok { NextAction = NextAction.Continue; UpdatedSettings = None } + Ok { NextAction = Continue; UpdatedSettings = None } // Settings summary elif checkCommand Commands.settingsSummary then Settings.printSummary settings printer None - Ok { NextAction = NextAction.Continue; UpdatedSettings = None } + Ok { NextAction = Continue; UpdatedSettings = None } // Toggle split chapters elif checkCommand Commands.splitChapterToggles then let newSettings = toggleSplitChapters settings printer.Info(summarizeToggle "Split Chapters" newSettings.SplitChapters) - Ok { NextAction = NextAction.Continue; UpdatedSettings = Some newSettings } + Ok { NextAction = Continue; UpdatedSettings = Some newSettings } // Toggle embed images elif checkCommand Commands.embedImagesToggles then let newSettings = toggleEmbedImages settings printer.Info(summarizeToggle "Embed Images" newSettings.EmbedImages) - Ok { NextAction = NextAction.Continue; UpdatedSettings = Some newSettings } + Ok { NextAction = Continue; UpdatedSettings = Some newSettings } // Toggle quiet mode elif checkCommand Commands.quietModeToggles then let newSettings = toggleQuietMode settings printer.Info(summarizeToggle "Quiet Mode" newSettings.QuietMode) printer.ShowDebug(not newSettings.QuietMode) - Ok { NextAction = NextAction.Continue; UpdatedSettings = Some newSettings } + Ok { NextAction = Continue; UpdatedSettings = Some newSettings } // Update audio formats elif command |> String.startsWithIgnoreCase Commands.updateAudioFormatPrefix then @@ -168,7 +168,7 @@ module Orchestrator = | Error err -> Error err | Ok newSettings -> printer.Info(summarizeUpdate "Audio Formats" (String.Join(", ", newSettings.AudioFormats))) - Ok { NextAction = NextAction.Continue; UpdatedSettings = Some newSettings } + Ok { NextAction = Continue; UpdatedSettings = Some newSettings } // Update audio quality elif command |> String.startsWithIgnoreCase Commands.updateAudioQualityPrefix then @@ -184,7 +184,7 @@ module Orchestrator = Error err | Ok updatedSettings -> printer.Info(summarizeUpdate "Audio Quality" (updatedSettings.AudioQuality.ToString())) - Ok { NextAction = NextAction.Continue; UpdatedSettings = Some updatedSettings } + Ok { NextAction = Continue; UpdatedSettings = Some updatedSettings } | _ -> Error $"\"%s{inputQuality}\" is an invalid quality value." From 40f6e5867fb9e6a125831ddb7aeb7842f583893c Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 15 Aug 2026 10:36:08 +0900 Subject: [PATCH 03/30] Fix incorrect input counts --- src/CCVTAC.Main/Orchestrator.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index 010b84e..e952c6f 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -224,7 +224,7 @@ module Orchestrator = let processInput category text index : Result = match category with | Command -> processCommand text settings history printer - | Url -> processUrl text settings resultTracker history inputTime categoryCounts[Url] index printer + | Url -> processUrl text settings resultTracker history inputTime categorizedInputs.Length index printer let rec loop inputs settings' nextAction' index = match inputs with From c1a0acf9350282a4dbf7d7f97f0ab72a696f85d8 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 15 Aug 2026 10:39:55 +0900 Subject: [PATCH 04/30] Print empty line on error too --- src/CCVTAC.Main/Downloading/Updater.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CCVTAC.Main/Downloading/Updater.fs b/src/CCVTAC.Main/Downloading/Updater.fs index 976c677..332a771 100644 --- a/src/CCVTAC.Main/Downloading/Updater.fs +++ b/src/CCVTAC.Main/Downloading/Updater.fs @@ -24,5 +24,5 @@ module Updater = printer.EmptyLines 1uy Ok () | Error err -> - printer.Error $"Failure updating: {err}" + printer.Error($"Failure updating: {err}", ?appendLines = Some 1uy) Error err From b23c4cb095d914eebd34b3f649e54f74bbf6a9c8 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 15 Aug 2026 17:31:58 +0900 Subject: [PATCH 05/30] Combine warnings into one message --- src/CCVTAC.Main/Downloading/Updater.fs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/CCVTAC.Main/Downloading/Updater.fs b/src/CCVTAC.Main/Downloading/Updater.fs index 332a771..c8292d8 100644 --- a/src/CCVTAC.Main/Downloading/Updater.fs +++ b/src/CCVTAC.Main/Downloading/Updater.fs @@ -7,20 +7,23 @@ open CCFSharpUtils.Text module Updater = + let successExitCode = 0 + let run userSettings (printer: Printer) : Result = if String.hasNoText userSettings.DownloaderUpdateCommand then printer.Info "No downloader update command provided, so will skip." Ok () else - let toolSettings = ToolSettings.create userSettings.DownloaderUpdateCommand userSettings.WorkingDirectory + let toolSettings = ToolSettings.create userSettings.DownloaderUpdateCommand + userSettings.WorkingDirectory match Runner.runTool toolSettings [] printer with | Ok result -> - if result.ExitCode <> 0 then - printer.Warning "Tool updated with minor issues." + if result.ExitCode <> successExitCode then match result.Error with - | Some w -> printer.Warning w - | None -> () + | Some w -> $"Update completed with minor issues: {w}" + | None -> "Update completed with minor unspecified issues." + |> printer.Warning printer.EmptyLines 1uy Ok () | Error err -> From e4087289ef6f47cc314fb769a2fe28537b07d4ca Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 15 Aug 2026 17:40:27 +0900 Subject: [PATCH 06/30] Convert Result return to unit --- src/CCVTAC.Main/Downloading/Updater.fs | 5 +---- src/CCVTAC.Main/Orchestrator.fs | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/CCVTAC.Main/Downloading/Updater.fs b/src/CCVTAC.Main/Downloading/Updater.fs index c8292d8..54fcd08 100644 --- a/src/CCVTAC.Main/Downloading/Updater.fs +++ b/src/CCVTAC.Main/Downloading/Updater.fs @@ -9,10 +9,9 @@ module Updater = let successExitCode = 0 - let run userSettings (printer: Printer) : Result = + let run userSettings (printer: Printer) : unit = if String.hasNoText userSettings.DownloaderUpdateCommand then printer.Info "No downloader update command provided, so will skip." - Ok () else let toolSettings = ToolSettings.create userSettings.DownloaderUpdateCommand userSettings.WorkingDirectory @@ -25,7 +24,5 @@ module Updater = | None -> "Update completed with minor unspecified issues." |> printer.Warning printer.EmptyLines 1uy - Ok () | Error err -> printer.Error($"Failure updating: {err}", ?appendLines = Some 1uy) - Error err diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index e952c6f..bb49bc1 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -128,9 +128,9 @@ module Orchestrator = history.ShowRecent printer Ok { NextAction = Continue; UpdatedSettings = None } - // Update downloader + // Update media downloader elif checkCommand Commands.updateDownloader then - Updater.run settings printer |> ignore + Updater.run settings printer Ok { NextAction = Continue; UpdatedSettings = None } // Settings summary From adb9b792ee406e57767fcae413e34971ecef6adf Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 15 Aug 2026 17:58:46 +0900 Subject: [PATCH 07/30] Minor code tweak --- src/CCVTAC.Main/Downloading/Updater.fs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/CCVTAC.Main/Downloading/Updater.fs b/src/CCVTAC.Main/Downloading/Updater.fs index 54fcd08..4fe1189 100644 --- a/src/CCVTAC.Main/Downloading/Updater.fs +++ b/src/CCVTAC.Main/Downloading/Updater.fs @@ -16,13 +16,15 @@ module Updater = let toolSettings = ToolSettings.create userSettings.DownloaderUpdateCommand userSettings.WorkingDirectory - match Runner.runTool toolSettings [] printer with - | Ok result -> - if result.ExitCode <> successExitCode then - match result.Error with - | Some w -> $"Update completed with minor issues: {w}" - | None -> "Update completed with minor unspecified issues." + let executionResult = Runner.runTool toolSettings [] printer + + match executionResult with + | Ok details -> + if details.ExitCode <> successExitCode then + match details.Error with + | Some errMsg -> $"Update completed with minor issues: {errMsg}" + | None -> "Update completed with minor unspecified issues." |> printer.Warning printer.EmptyLines 1uy - | Error err -> - printer.Error($"Failure updating: {err}", ?appendLines = Some 1uy) + | Error msg -> + printer.Error($"Failure updating: {msg}", ?appendLines = Some 1uy) From 857b66862f98b2655cc8953839d3d45221621690 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 15 Aug 2026 18:01:26 +0900 Subject: [PATCH 08/30] Add EmptyLine() method to Printer --- src/CCVTAC.Main/Downloading/Updater.fs | 2 +- src/CCVTAC.Main/Printer.fs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/CCVTAC.Main/Downloading/Updater.fs b/src/CCVTAC.Main/Downloading/Updater.fs index 4fe1189..a40e8b6 100644 --- a/src/CCVTAC.Main/Downloading/Updater.fs +++ b/src/CCVTAC.Main/Downloading/Updater.fs @@ -25,6 +25,6 @@ module Updater = | Some errMsg -> $"Update completed with minor issues: {errMsg}" | None -> "Update completed with minor unspecified issues." |> printer.Warning - printer.EmptyLines 1uy + printer.EmptyLine() | Error msg -> printer.Error($"Failure updating: {msg}", ?appendLines = Some 1uy) diff --git a/src/CCVTAC.Main/Printer.fs b/src/CCVTAC.Main/Printer.fs index e329383..a2f68c2 100644 --- a/src/CCVTAC.Main/Printer.fs +++ b/src/CCVTAC.Main/Printer.fs @@ -136,6 +136,8 @@ type Printer(showDebug: bool) = this.Print(Level.Debug, message, ?appendLineBreak = appendLineBreak, ?prependLines = prependLines, ?appendLines = appendLines, ?processMarkup = processMarkup) + member this.EmptyLine() = Printer.EmptyLines 1uy + member this.EmptyLines(count: byte) = Printer.EmptyLines count /// Prints the requested number of blank lines. From 5deaf03566e881b843cbfe5fe3c282514f7e7f24 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 15 Aug 2026 18:04:56 +0900 Subject: [PATCH 09/30] Remove superfluous type name --- src/CCVTAC.Main/Orchestrator.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index bb49bc1..37eb8cf 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -284,10 +284,10 @@ module Orchestrator = let results = ResultTracker printer let history = History(settings.HistoryFile, settings.HistoryDisplayCount) - let mutable nextAction = NextAction.Continue + let mutable nextAction = Continue let mutable currentSettings = settings - while nextAction = NextAction.Continue do + while nextAction = Continue do let input = printer.GetInput prompt let splitInputs = splitInputText input From 1fd5ad7286d7a7da46fe37c7f87c8f7b8f4f090b Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 15 Aug 2026 18:09:02 +0900 Subject: [PATCH 10/30] Remove superfluous type name --- src/CCVTAC.Main/Orchestrator.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index 37eb8cf..45faf06 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -30,11 +30,11 @@ module Orchestrator = : unit = if List.hasMultiple categorizedInputs then - let urlSummary = String.pluralizeSWithCount "URL" counts[InputCategory.Url] - let cmdSummary = String.pluralizeSWithCount "command" counts[InputCategory.Command] + let urlSummary = String.pluralizeSWithCount "URL" counts[Url] + let cmdSummary = String.pluralizeSWithCount "command" counts[Command] printer.Info <| - match counts[InputCategory.Url], counts[InputCategory.Command] with + match counts[Url], counts[Command] with | u, c when u > 0 && c > 0 -> $"Batch of %s{urlSummary} and %s{cmdSummary} entered:" | u, _ when u > 0 -> $"Batch of %s{urlSummary} entered:" | _, c when c > 0 -> $"Batch of %s{cmdSummary} entered:" From 4fb819a32b26ce59eecff9070d53621404ab5b67 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 15 Aug 2026 18:12:41 +0900 Subject: [PATCH 11/30] Use EmptyLine() --- src/CCVTAC.Main/Orchestrator.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index 45faf06..62447f4 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -43,7 +43,7 @@ module Orchestrator = for input in categorizedInputs do printer.Info $" • %s{input.Text}" - Printer.EmptyLines 1uy + printer.EmptyLine() let processUrl (url: string) From 8a7ab70c4075b753e2d96079cfef35507de17114 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 15 Aug 2026 18:39:38 +0900 Subject: [PATCH 12/30] Rename ResultMessageCollection to ResultMessages --- src/CCVTAC.Main/IoUtilities/Directories.fs | 4 ++-- src/CCVTAC.Main/Shared.fs | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/CCVTAC.Main/IoUtilities/Directories.fs b/src/CCVTAC.Main/IoUtilities/Directories.fs index acd98fa..fbc196f 100644 --- a/src/CCVTAC.Main/IoUtilities/Directories.fs +++ b/src/CCVTAC.Main/IoUtilities/Directories.fs @@ -35,7 +35,7 @@ module Directories = |> Array.filter (fun filePath -> not (ignoreFiles |> Array.exists filePath.EndsWith))) let deleteAllFiles workingDirectory - : Result = + : Result = let delete fileNames = let successes, failures = ResizeArray(), ResizeArray() @@ -60,7 +60,7 @@ module Directories = then deleteAllFiles dirName else Error "Will not delete the files." - let printDeletionResults (printer: Printer) (results: ResultMessageCollection) : unit = + let printDeletionResults (printer: Printer) (results: ResultMessages) : unit = printer.Info $"Deleted %s{String.fileLabel results.Successes.Length}." results.Successes |> List.iter printer.Debug diff --git a/src/CCVTAC.Main/Shared.fs b/src/CCVTAC.Main/Shared.fs index 7c6d7ff..5a26f1a 100644 --- a/src/CCVTAC.Main/Shared.fs +++ b/src/CCVTAC.Main/Shared.fs @@ -6,7 +6,7 @@ open Spectre.Console [] module Shared = - type ResultMessageCollection = { Successes: string list; Failures: string list } + type ResultMessages = { Successes: string list; Failures: string list } let sleep workingMsgFn doneMsgFn seconds : string = let rec loop remaining (ctx: StatusContext) = @@ -17,10 +17,9 @@ module Shared = AnsiConsole .Status() - .Start((workingMsgFn seconds), fun ctx -> + .Start(workingMsgFn seconds, fun ctx -> ctx.Spinner(Spinner.Known.Star) .SpinnerStyle(Style.Parse "blue") |> loop seconds) doneMsgFn seconds - From 704018d95f06828c8cfa6630790b1c7dc76feac3 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 15 Aug 2026 18:44:54 +0900 Subject: [PATCH 13/30] Change retries from 2 to 3 --- src/CCVTAC.Main/Downloading/Downloader.fs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/CCVTAC.Main/Downloading/Downloader.fs b/src/CCVTAC.Main/Downloading/Downloader.fs index 8b65a48..a709633 100644 --- a/src/CCVTAC.Main/Downloading/Downloader.fs +++ b/src/CCVTAC.Main/Downloading/Downloader.fs @@ -8,7 +8,6 @@ open CCVTAC.Main.Downloading.Downloading open CCVTAC.Main.ExternalTools open CCVTAC.Main.Settings.Settings open CCFSharpUtils -open CCFSharpUtils.Text open FsToolkit.ErrorHandling open System @@ -37,7 +36,7 @@ module Downloader = "--write-thumbnail --convert-thumbnails jpg" writeJsonArg trimFileNamesArg - "--retries 2" ] + "--retries 3" ] |> Set.ofList if userSettings.QuietMode then From c20ed8c4f7efbfdeea76c6a29ca51d05547c2870 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Tue, 18 Aug 2026 17:49:07 +0900 Subject: [PATCH 14/30] Show warnings after successful download --- src/CCVTAC.Main/Downloading/Downloader.fs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CCVTAC.Main/Downloading/Downloader.fs b/src/CCVTAC.Main/Downloading/Downloader.fs index a709633..9c7fb2d 100644 --- a/src/CCVTAC.Main/Downloading/Downloader.fs +++ b/src/CCVTAC.Main/Downloading/Downloader.fs @@ -139,7 +139,8 @@ module Downloader = let urls = { Primary = PrimaryUrl rawUrls[0] Metadata = SupplementaryUrl <| if rawUrls.Length = 2 then Some rawUrls[1] else None } - let! _ = downloadMedia printer mediaType userSettings urls.Primary + let! warnings = downloadMedia printer mediaType userSettings urls.Primary + warnings |> List.iter printer.Info let! metadataDownloadResult = downloadMetadata printer userSettings urls.Metadata return! Ok metadataDownloadResult } From 091835dcf5261927015633b14680dc322e52fe18 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Tue, 18 Aug 2026 18:13:58 +0900 Subject: [PATCH 15/30] Delete leftover files after download failure (Fixes regression) --- src/CCVTAC.Main/IoUtilities/Directories.fs | 7 ++-- src/CCVTAC.Main/Orchestrator.fs | 45 +++++++++++++++------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/CCVTAC.Main/IoUtilities/Directories.fs b/src/CCVTAC.Main/IoUtilities/Directories.fs index fbc196f..9195e27 100644 --- a/src/CCVTAC.Main/IoUtilities/Directories.fs +++ b/src/CCVTAC.Main/IoUtilities/Directories.fs @@ -34,8 +34,7 @@ module Directories = Directory.GetFiles(directoryName, allFilesSearchPattern, EnumerationOptions()) |> Array.filter (fun filePath -> not (ignoreFiles |> Array.exists filePath.EndsWith))) - let deleteAllFiles workingDirectory - : Result = + let deleteAllFiles workingDirectory : Result = let delete fileNames = let successes, failures = ResizeArray(), ResizeArray() @@ -68,7 +67,7 @@ module Directories = printer.Warning $"However, %s{String.fileLabel results.Failures.Length} could not be deleted:" results.Failures |> List.iter printer.Error - let warnIfAnyFiles showMax dirName = + let warnIfAnyFiles showMax dirName : Result = match getDirectoryFileNames dirName None with | Error errMsg -> Error errMsg | Ok fileNames -> @@ -85,7 +84,7 @@ module Directories = if fileNames.Length > showMax then sb.AppendLine $"... plus {fileNames.Length - showMax} more." else sb - |> _.AppendLine("This sometimes occurs due to the same video appearing twice in playlists.") + // |> _.AppendLine("This sometimes occurs due to the same video appearing twice in playlists.") |> _.ToString() |> Error diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index 62447f4..036b3c6 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -226,24 +226,43 @@ module Orchestrator = | Command -> processCommand text settings history printer | Url -> processUrl text settings resultTracker history inputTime categorizedInputs.Length index printer + let deleteLeftOverFiles dir = + match Directories.warnIfAnyFiles 10 dir with + | Ok () -> Ok () + | Error filesFoundErr -> + printer.Error filesFoundErr + Directories.deleteAllFiles dir |> function + | Ok results -> + Directories.printDeletionResults printer results + Ok () + | Error deletionError -> + printer.Error deletionError + printer.Info "Aborting..." + Error "Could not delete files" + let rec loop inputs settings' nextAction' index = match inputs with | [] -> (nextAction', settings', index) | input :: remainingInputs when nextAction' = Continue -> - let result = processInput input.Category input.Text index - batchResults.RegisterResult(input.Text, result) - - match result with - | Error err -> - printer.Error err - if List.isNotEmpty remainingInputs then printSleep input.Category - loop remainingInputs settings' nextAction' (index + 1) - | Ok processResult -> - if List.isNotEmpty remainingInputs then printSleep input.Category - let newSettings = processResult.UpdatedSettings |> Option.defaultValue settings' - let newNextAction = processResult.NextAction - loop remainingInputs newSettings newNextAction (index + 1) + let processResult = processInput input.Category input.Text index + batchResults.RegisterResult(input.Text, processResult) + + // Deleting the files here might make debugging issues a bit tougher. + match deleteLeftOverFiles settings.WorkingDirectory with + | Error _ -> + (QuitDueToErrors, settings', index) + | Ok () -> + match processResult with + | Error err -> + printer.Error err + if List.isNotEmpty remainingInputs then printSleep input.Category + loop remainingInputs settings' nextAction' (index + 1) + | Ok processResult -> + if List.isNotEmpty remainingInputs then printSleep input.Category + let newSettings = processResult.UpdatedSettings |> Option.defaultValue settings' + let newNextAction = processResult.NextAction + loop remainingInputs newSettings newNextAction (index + 1) | _ -> (nextAction', settings', index) From 9a2f3729c8529ef503dd694bf27bf6dead812683 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Wed, 19 Aug 2026 14:45:36 +0900 Subject: [PATCH 16/30] Return error without printing --- src/CCVTAC.Main/Orchestrator.fs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index 036b3c6..7d61234 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -226,19 +226,17 @@ module Orchestrator = | Command -> processCommand text settings history printer | Url -> processUrl text settings resultTracker history inputTime categorizedInputs.Length index printer - let deleteLeftOverFiles dir = - match Directories.warnIfAnyFiles 10 dir with + let deleteLeftoverFiles dirName : Result = + match Directories.warnIfAnyFiles 10 dirName with | Ok () -> Ok () | Error filesFoundErr -> printer.Error filesFoundErr - Directories.deleteAllFiles dir |> function + Directories.deleteAllFiles dirName |> function | Ok results -> Directories.printDeletionResults printer results Ok () | Error deletionError -> - printer.Error deletionError - printer.Info "Aborting..." - Error "Could not delete files" + Error $"Error deleting leftover files after download: {deletionError}" let rec loop inputs settings' nextAction' index = match inputs with @@ -249,7 +247,7 @@ module Orchestrator = batchResults.RegisterResult(input.Text, processResult) // Deleting the files here might make debugging issues a bit tougher. - match deleteLeftOverFiles settings.WorkingDirectory with + match deleteLeftoverFiles settings.WorkingDirectory with | Error _ -> (QuitDueToErrors, settings', index) | Ok () -> From a4b55d557baf15316d28eb445b32492e4098da1b Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Wed, 19 Aug 2026 16:16:57 +0900 Subject: [PATCH 17/30] Return confirmation message upon successful deletion --- src/CCVTAC.Main/Orchestrator.fs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index 7d61234..c5db036 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -226,19 +226,19 @@ module Orchestrator = | Command -> processCommand text settings history printer | Url -> processUrl text settings resultTracker history inputTime categorizedInputs.Length index printer - let deleteLeftoverFiles dirName : Result = + let deleteLeftoverFiles dirName : Result = match Directories.warnIfAnyFiles 10 dirName with - | Ok () -> Ok () + | Ok () -> Ok "No leftover files found." | Error filesFoundErr -> - printer.Error filesFoundErr + printer.Error filesFoundErr // Might not need this. Directories.deleteAllFiles dirName |> function | Ok results -> Directories.printDeletionResults printer results - Ok () + Ok "Files deleted successfully." | Error deletionError -> Error $"Error deleting leftover files after download: {deletionError}" - let rec loop inputs settings' nextAction' index = + let rec loop inputs settings' nextAction' index : NextAction * UserSettings * int = match inputs with | [] -> (nextAction', settings', index) @@ -248,9 +248,11 @@ module Orchestrator = // Deleting the files here might make debugging issues a bit tougher. match deleteLeftoverFiles settings.WorkingDirectory with - | Error _ -> + | Error errMsg -> + printer.Error errMsg (QuitDueToErrors, settings', index) - | Ok () -> + | Ok message -> + printer.Debug message match processResult with | Error err -> printer.Error err From 0d0c5dcb530774dbc4a994c3cd103b37e68a91e4 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Wed, 19 Aug 2026 20:38:36 +0900 Subject: [PATCH 18/30] Rename variable --- 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 c5db036..07efbd5 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -199,7 +199,7 @@ module Orchestrator = /// Processes a single user request, from input to downloading and file post-processing. /// Returns the next action the application should take (e.g., continue or quit). let processBatch - (categorizedInputs: CategorizedInput list) + (inputs: CategorizedInput list) (categoryCounts: CategoryCounts) (settings: UserSettings) (resultTracker: ResultTracker) @@ -224,7 +224,7 @@ module Orchestrator = let processInput category text index : Result = match category with | Command -> processCommand text settings history printer - | Url -> processUrl text settings resultTracker history inputTime categorizedInputs.Length index printer + | Url -> processUrl text settings resultTracker history inputTime inputs.Length index printer let deleteLeftoverFiles dirName : Result = match Directories.warnIfAnyFiles 10 dirName with @@ -267,7 +267,7 @@ module Orchestrator = (nextAction', settings', index) let (finalNextAction, finalSettings, processedCount) = - loop categorizedInputs settings Continue 1 + loop inputs settings Continue 1 if categoryCounts[Url] > 1 then printer.Info( @@ -278,9 +278,9 @@ module Orchestrator = ) batchResults.PrintBatchFailures() - if processedCount <= categorizedInputs.Length then + if processedCount <= inputs.Length then let unprocessedInputs = - categorizedInputs[processedCount-1..] + inputs[processedCount-1..] |> List.map (fun x -> $"• {x.Text}") |> String.concat String.nl printer.Warning $"Some inputs were not yet processed: {String.nl}{unprocessedInputs}" From e02dafd8b70d86218387576001ab1b2fb113a8c3 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Wed, 19 Aug 2026 20:53:58 +0900 Subject: [PATCH 19/30] Refactor deleteAllFiles func --- src/CCVTAC.Main/IoUtilities/Directories.fs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/CCVTAC.Main/IoUtilities/Directories.fs b/src/CCVTAC.Main/IoUtilities/Directories.fs index 9195e27..d1b49ad 100644 --- a/src/CCVTAC.Main/IoUtilities/Directories.fs +++ b/src/CCVTAC.Main/IoUtilities/Directories.fs @@ -35,7 +35,6 @@ module Directories = |> Array.filter (fun filePath -> not (ignoreFiles |> Array.exists filePath.EndsWith))) let deleteAllFiles workingDirectory : Result = - let delete fileNames = let successes, failures = ResizeArray(), ResizeArray() @@ -46,12 +45,11 @@ module Directories = with exn -> failures.Add $"• Error deleting \"%s{fileName}\": %s{exn.Message}" - { Successes = successes |> Seq.toList |> List.rev - Failures = failures |> Seq.toList |> List.rev } + { Successes = List.ofSeq successes + Failures = List.ofSeq failures } - match getDirectoryFileNames workingDirectory None with - | Error errMsg -> Error errMsg - | Ok fileNames -> Ok (delete fileNames) + getDirectoryFileNames workingDirectory None + |> Result.map delete /// Ask the user to confirm the deletion of files in the specified directory. let askToDeleteAllFiles dirName (printer: Printer) = From 05d56e0a37712ae1f13f727bd05996471d70722d Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Wed, 19 Aug 2026 20:55:23 +0900 Subject: [PATCH 20/30] Convert array to list --- src/CCVTAC.Main/IoUtilities/Directories.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CCVTAC.Main/IoUtilities/Directories.fs b/src/CCVTAC.Main/IoUtilities/Directories.fs index d1b49ad..9e58b9a 100644 --- a/src/CCVTAC.Main/IoUtilities/Directories.fs +++ b/src/CCVTAC.Main/IoUtilities/Directories.fs @@ -28,11 +28,11 @@ module Directories = customIgnoreFiles |> Option.defaultValue Seq.empty |> Seq.distinct - |> Seq.toArray + |> Seq.toList ofTry (fun _ -> Directory.GetFiles(directoryName, allFilesSearchPattern, EnumerationOptions()) - |> Array.filter (fun filePath -> not (ignoreFiles |> Array.exists filePath.EndsWith))) + |> Array.filter (fun filePath -> not (ignoreFiles |> List.exists filePath.EndsWith))) let deleteAllFiles workingDirectory : Result = let delete fileNames = From 17a5b18c8c49b6c3eb99f502789ec058ac8f506f Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Wed, 19 Aug 2026 20:58:27 +0900 Subject: [PATCH 21/30] Nomenclature --- src/CCVTAC.Main/IoUtilities/Directories.fs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/CCVTAC.Main/IoUtilities/Directories.fs b/src/CCVTAC.Main/IoUtilities/Directories.fs index 9e58b9a..be2f706 100644 --- a/src/CCVTAC.Main/IoUtilities/Directories.fs +++ b/src/CCVTAC.Main/IoUtilities/Directories.fs @@ -13,25 +13,25 @@ module Directories = let private allFilesSearchPattern = "*" /// Counts the number of audio files in a directory. - let audioFileCount (directory: string) (includedExtensions: string list) = - DirectoryInfo(directory).EnumerateFiles() + let audioFileCount dirName includedExtensions = + DirectoryInfo(dirName).EnumerateFiles() |> Seq.filter (fun f -> List.containsIgnoreCase f.Extension includedExtensions) |> Seq.length /// Returns the filenames in a given directory, optionally ignoring specific filenames. let private getDirectoryFileNames - (directoryName: string) - (customIgnoreFiles: string seq option) + dirName + (ignoreFilesOpt: string seq option) : Result = let ignoreFiles = - customIgnoreFiles + ignoreFilesOpt |> Option.defaultValue Seq.empty |> Seq.distinct |> Seq.toList ofTry (fun _ -> - Directory.GetFiles(directoryName, allFilesSearchPattern, EnumerationOptions()) + Directory.GetFiles(dirName, allFilesSearchPattern, EnumerationOptions()) |> Array.filter (fun filePath -> not (ignoreFiles |> List.exists filePath.EndsWith))) let deleteAllFiles workingDirectory : Result = From 17d426370b13b07558a71bc90f439c4b13a55c0b Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Wed, 19 Aug 2026 21:02:28 +0900 Subject: [PATCH 22/30] Change seq to list --- src/CCVTAC.Main/IoUtilities/Directories.fs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/CCVTAC.Main/IoUtilities/Directories.fs b/src/CCVTAC.Main/IoUtilities/Directories.fs index be2f706..54ac501 100644 --- a/src/CCVTAC.Main/IoUtilities/Directories.fs +++ b/src/CCVTAC.Main/IoUtilities/Directories.fs @@ -19,14 +19,10 @@ module Directories = |> Seq.length /// Returns the filenames in a given directory, optionally ignoring specific filenames. - let private getDirectoryFileNames - dirName - (ignoreFilesOpt: string seq option) - : Result = - - let ignoreFiles = + let private getDirectoryFileNames dirName ignoreFilesOpt : Result = + let ignoreFiles : string list = ignoreFilesOpt - |> Option.defaultValue Seq.empty + |> Option.defaultValue List.empty |> Seq.distinct |> Seq.toList From 24983717b00ea479ff11c1542d04b563bed4a2bb Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Thu, 20 Aug 2026 21:52:11 +0900 Subject: [PATCH 23/30] Mild tweaks --- src/CCVTAC.Main/IoUtilities/Directories.fs | 2 +- src/CCVTAC.Main/Orchestrator.fs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CCVTAC.Main/IoUtilities/Directories.fs b/src/CCVTAC.Main/IoUtilities/Directories.fs index 54ac501..1028380 100644 --- a/src/CCVTAC.Main/IoUtilities/Directories.fs +++ b/src/CCVTAC.Main/IoUtilities/Directories.fs @@ -58,7 +58,7 @@ module Directories = results.Successes |> List.iter printer.Debug if List.isNotEmpty results.Failures then - printer.Warning $"However, %s{String.fileLabel results.Failures.Length} could not be deleted:" + printer.Error $"%s{String.fileLabel results.Failures.Length} could not be deleted:" results.Failures |> List.iter printer.Error let warnIfAnyFiles showMax dirName : Result = diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index 07efbd5..4f7205b 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -322,7 +322,7 @@ module Orchestrator = nextAction <- batchResult.NextAction match batchResult.UpdatedSettings with - | Some s -> currentSettings <- s + | Some newSettings -> currentSettings <- newSettings | None -> () results.PrintSessionSummary() From fbc291263f1ff5a4859699915e2541105e9b3009 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 22 Aug 2026 20:08:34 +0900 Subject: [PATCH 24/30] Make printer args first --- src/CCVTAC.Main/Downloading/Downloader.fs | 6 ++-- src/CCVTAC.Main/Downloading/Updater.fs | 4 +-- src/CCVTAC.Main/ExternalTools/Runner.fs | 2 +- src/CCVTAC.Main/IoUtilities/Directories.fs | 2 +- src/CCVTAC.Main/Orchestrator.fs | 28 +++++++++---------- src/CCVTAC.Main/PostProcessing/Deleter.fs | 6 ++-- .../PostProcessing/ImageProcessor.fs | 4 +-- src/CCVTAC.Main/PostProcessing/Mover.fs | 2 +- .../PostProcessing/PostProcessing.fs | 12 ++++---- src/CCVTAC.Main/PostProcessing/Renamer.fs | 6 ++-- .../PostProcessing/Tagging/Tagger.fs | 18 ++++++------ src/CCVTAC.Main/Program.fs | 6 ++-- src/CCVTAC.Main/Settings/Settings.fs | 2 +- src/CCVTAC.Tests/RenamerTests.fs | 2 +- 14 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/CCVTAC.Main/Downloading/Downloader.fs b/src/CCVTAC.Main/Downloading/Downloader.fs index 9c7fb2d..239a111 100644 --- a/src/CCVTAC.Main/Downloading/Downloader.fs +++ b/src/CCVTAC.Main/Downloading/Downloader.fs @@ -86,7 +86,7 @@ module Downloader = let commandWithArgs = $"{programName} {args}" let downloadSettings = ToolSettings.create commandWithArgs userSettings.WorkingDirectory - let downloadResult = runTool downloadSettings [1] printer + let downloadResult = runTool printer downloadSettings [1] let anyFilesDownloaded = Num.isPos <| audioFileCount userSettings.WorkingDirectory Files.audioFileExts match downloadResult, anyFilesDownloaded with @@ -127,13 +127,13 @@ module Downloader = let args = generateDownloadArgs None userSettings None (Some [url']) let commandWithArgs = $"{programName} {args}" let downloadSettings = ToolSettings.create commandWithArgs userSettings.WorkingDirectory - let metadataDownloadResult = runTool downloadSettings [1] printer + let metadataDownloadResult = runTool printer downloadSettings [1] match metadataDownloadResult with | Ok _ -> Ok "Supplementary metadata download completed OK." | Error err -> Error [$"Supplementary metadata download failed: {err}"] - let run (mediaType: MediaType) userSettings (printer: Printer) : Result = + let run (printer: Printer) (mediaType: MediaType) userSettings : Result = result { let rawUrls = generateDownloadUrl mediaType let urls = diff --git a/src/CCVTAC.Main/Downloading/Updater.fs b/src/CCVTAC.Main/Downloading/Updater.fs index a40e8b6..090825b 100644 --- a/src/CCVTAC.Main/Downloading/Updater.fs +++ b/src/CCVTAC.Main/Downloading/Updater.fs @@ -9,14 +9,14 @@ module Updater = let successExitCode = 0 - let run userSettings (printer: Printer) : unit = + let run (printer: Printer) userSettings : unit = if String.hasNoText userSettings.DownloaderUpdateCommand then printer.Info "No downloader update command provided, so will skip." else let toolSettings = ToolSettings.create userSettings.DownloaderUpdateCommand userSettings.WorkingDirectory - let executionResult = Runner.runTool toolSettings [] printer + let executionResult = Runner.runTool printer toolSettings [] match executionResult with | Ok details -> diff --git a/src/CCVTAC.Main/ExternalTools/Runner.fs b/src/CCVTAC.Main/ExternalTools/Runner.fs index 9ce28ec..1c99276 100644 --- a/src/CCVTAC.Main/ExternalTools/Runner.fs +++ b/src/CCVTAC.Main/ExternalTools/Runner.fs @@ -21,7 +21,7 @@ module Runner = /// Tool settings for execution /// Additional exit codes, other than 0, that can be treated as non-failures /// - let runTool toolSettings otherSuccessExitCodes (printer: Printer) : Result = + let runTool (printer: Printer) toolSettings otherSuccessExitCodes : Result = let watch = Watch() printer.Info $"Running {toolSettings.CommandWithArgs}..." diff --git a/src/CCVTAC.Main/IoUtilities/Directories.fs b/src/CCVTAC.Main/IoUtilities/Directories.fs index 1028380..aab42f1 100644 --- a/src/CCVTAC.Main/IoUtilities/Directories.fs +++ b/src/CCVTAC.Main/IoUtilities/Directories.fs @@ -48,7 +48,7 @@ module Directories = |> Result.map delete /// Ask the user to confirm the deletion of files in the specified directory. - let askToDeleteAllFiles dirName (printer: Printer) = + let askToDeleteAllFiles (printer: Printer) dirName = if printer.AskToBool("Delete all temporary files?", "Yes", "No") then deleteAllFiles dirName else Error "Will not delete the files." diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index 4f7205b..a46ed9c 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -24,9 +24,9 @@ module Orchestrator = UpdatedSettings: UserSettings option } let summarizeInput + (printer: Printer) (categorizedInputs: CategorizedInput list) (counts: CategoryCounts) - (printer: Printer) : unit = if List.hasMultiple categorizedInputs then @@ -46,6 +46,7 @@ module Orchestrator = printer.EmptyLine() let processUrl + (printer: Printer) (url: string) (settings: UserSettings) (resultTracker: ResultTracker) @@ -53,7 +54,6 @@ module Orchestrator = (urlInputTime: DateTime) (batchSize: int) (urlIndex: int) - (printer: Printer) : Result = match Directories.warnIfAnyFiles 10 settings.WorkingDirectory with @@ -75,7 +75,7 @@ module Orchestrator = printer.Info $"%s{mediaType.GetType().Name} URL '%s{url}' detected." history.Append(url, urlInputTime, printer) - let downloadResult = Downloader.run mediaType settings printer + let downloadResult = Downloader.run printer mediaType settings resultTracker.RegisterResult(url, downloadResult) match downloadResult with @@ -87,7 +87,7 @@ module Orchestrator = | Ok message -> printer.Debug "Download successful." if String.hasText message then printer.Info message - PostProcessor.run settings mediaType printer + PostProcessor.run printer settings mediaType let groupClause = if batchSize > 1 @@ -104,10 +104,10 @@ module Orchestrator = sprintf "%s was updated to \"%s\" for this session." settingName setting let processCommand + (printer: Printer) (command: string) (settings: UserSettings) (history: History) - (printer: Printer) : Result = let checkCommand = List.containsIgnoreCase command @@ -130,12 +130,12 @@ module Orchestrator = // Update media downloader elif checkCommand Commands.updateDownloader then - Updater.run settings printer + Updater.run printer settings Ok { NextAction = Continue; UpdatedSettings = None } // Settings summary elif checkCommand Commands.settingsSummary then - Settings.printSummary settings printer None + Settings.printSummary printer settings None Ok { NextAction = Continue; UpdatedSettings = None } // Toggle split chapters @@ -199,12 +199,12 @@ module Orchestrator = /// Processes a single user request, from input to downloading and file post-processing. /// Returns the next action the application should take (e.g., continue or quit). let processBatch + (printer: Printer) (inputs: CategorizedInput list) (categoryCounts: CategoryCounts) (settings: UserSettings) (resultTracker: ResultTracker) (history: History) - (printer: Printer) : BatchResults = let inputTime = DateTime.Now @@ -223,8 +223,8 @@ module Orchestrator = let processInput category text index : Result = match category with - | Command -> processCommand text settings history printer - | Url -> processUrl text settings resultTracker history inputTime inputs.Length index printer + | Command -> processCommand printer text settings history + | Url -> processUrl printer text settings resultTracker history inputTime inputs.Length index let deleteLeftoverFiles dirName : Result = match Directories.warnIfAnyFiles 10 dirName with @@ -289,13 +289,13 @@ module Orchestrator = UpdatedSettings = Some finalSettings } /// Ensures the download environment is ready, then initiates the input and download process. - let start (settings: UserSettings) (printer: Printer) : unit = + let start (printer: Printer) (settings: UserSettings) : unit = // The working directory should start empty. Give the user a chance to empty it. match Directories.warnIfAnyFiles 10 settings.WorkingDirectory with | Ok () -> () | Error filesFoundErr -> printer.Error filesFoundErr - Directories.askToDeleteAllFiles settings.WorkingDirectory printer |> function + Directories.askToDeleteAllFiles printer settings.WorkingDirectory |> function | Ok results -> Directories.printDeletionResults printer results | Error deletionError -> printer.Error deletionError @@ -316,9 +316,9 @@ module Orchestrator = | _ -> let categorizedInputs = categorizeInputs splitInputs let categoryCounts = countCategories categorizedInputs - summarizeInput categorizedInputs categoryCounts printer + summarizeInput printer categorizedInputs categoryCounts - let batchResult = processBatch categorizedInputs categoryCounts currentSettings results history printer + let batchResult = processBatch printer categorizedInputs categoryCounts currentSettings results history nextAction <- batchResult.NextAction match batchResult.UpdatedSettings with diff --git a/src/CCVTAC.Main/PostProcessing/Deleter.fs b/src/CCVTAC.Main/PostProcessing/Deleter.fs index c0a64c8..53527b5 100644 --- a/src/CCVTAC.Main/PostProcessing/Deleter.fs +++ b/src/CCVTAC.Main/PostProcessing/Deleter.fs @@ -16,7 +16,7 @@ module Deleter = try Ok (Directory.GetFiles(workingDirectory, $"*{metadata.Id}*")) with exn -> Error $"Error collecting filenames: {exn.Message}" - let private deleteAll (fileNames: string array) (printer: Printer) : unit = + let private deleteAll (printer: Printer) (fileNames: string array) : unit = fileNames |> Array.iter (fun fileName -> try @@ -27,10 +27,10 @@ module Deleter = ) let run + (printer: Printer) (taggingSetFileNames: string seq) (collectionMetadata: CollectionMetadata option) (workingDirectory: string) - (printer: Printer) : unit = let collectionFileNames = @@ -48,5 +48,5 @@ module Deleter = printer.Warning "No files to delete were found." else printer.Debug $"""Deleting {String.fileLabelWithDesc "temporary" allFileNames.Length}...""" - deleteAll allFileNames printer + deleteAll printer allFileNames printer.Info "Deleted temporary files." diff --git a/src/CCVTAC.Main/PostProcessing/ImageProcessor.fs b/src/CCVTAC.Main/PostProcessing/ImageProcessor.fs index ee62388..d8a901f 100644 --- a/src/CCVTAC.Main/PostProcessing/ImageProcessor.fs +++ b/src/CCVTAC.Main/PostProcessing/ImageProcessor.fs @@ -6,6 +6,6 @@ module ImageProcessor = let private programName = "mogrify" - let run workingDirectory printer : unit = + let run printer workingDirectory : unit = let toolSettings = workingDirectory |> ToolSettings.create $"{programName} -trim -fuzz 10%% *.jpg" - Runner.runTool toolSettings [] printer |> ignore + Runner.runTool printer toolSettings [] |> ignore diff --git a/src/CCVTAC.Main/PostProcessing/Mover.fs b/src/CCVTAC.Main/PostProcessing/Mover.fs index f3674c1..5b122f1 100644 --- a/src/CCVTAC.Main/PostProcessing/Mover.fs +++ b/src/CCVTAC.Main/PostProcessing/Mover.fs @@ -107,11 +107,11 @@ module Mover = safeName.Replace(topicSuffix, String.Empty) let run + (printer: Printer) (taggingSets: TaggingSet seq) (maybeCollectionData: CollectionMetadata option) (settings: UserSettings) (overwrite: bool) - (printer: Printer) : unit = printer.Debug "Starting move..." diff --git a/src/CCVTAC.Main/PostProcessing/PostProcessing.fs b/src/CCVTAC.Main/PostProcessing/PostProcessing.fs index 103e0e9..12aba50 100644 --- a/src/CCVTAC.Main/PostProcessing/PostProcessing.fs +++ b/src/CCVTAC.Main/PostProcessing/PostProcessing.fs @@ -53,7 +53,7 @@ module PostProcessor = with exn -> Error $"Error reading working files in \"{dir}\" for tagging set creation: %s{exn.Message}" - let run settings mediaType (printer: Printer) : unit = + let run (printer: Printer) settings mediaType : unit = let watch = Watch() let workingDirectory = settings.WorkingDirectory @@ -73,16 +73,16 @@ module PostProcessor = Some cm if settings.EmbedImages then - ImageProcessor.run workingDirectory printer + ImageProcessor.run printer workingDirectory - match Tagger.run settings taggingSets collectionJson mediaType printer with + match Tagger.run printer settings taggingSets collectionJson mediaType with | Ok msg -> printer.Info msg - Renamer.run settings workingDirectory printer - Mover.run taggingSets collectionJson settings true printer + Renamer.run printer settings workingDirectory + Mover.run printer taggingSets collectionJson settings true let allTaggingSetFiles = taggingSets |> List.collect allFiles - Deleter.run allTaggingSetFiles collectionJson workingDirectory printer + Deleter.run printer allTaggingSetFiles collectionJson workingDirectory match Directories.warnIfAnyFiles 20 workingDirectory with | Ok _ -> () diff --git a/src/CCVTAC.Main/PostProcessing/Renamer.fs b/src/CCVTAC.Main/PostProcessing/Renamer.fs index 2a7600e..c76460d 100644 --- a/src/CCVTAC.Main/PostProcessing/Renamer.fs +++ b/src/CCVTAC.Main/PostProcessing/Renamer.fs @@ -21,7 +21,7 @@ module Renamer = | "KC" -> NormalizationForm.FormKC | _ -> NormalizationForm.FormC - let updateTextViaPattern isQuietMode (printer: Printer) (text: SB) (renamePattern: RenamePattern) : SB = + let updateTextViaPattern (printer: Printer) isQuietMode (text: SB) (renamePattern: RenamePattern) : SB = let regex = Regex renamePattern.RegexPattern let matches = text.ToString() |> regex.Matches |> Rgx.successMatches |> Seq.rev |> Seq.toList @@ -55,7 +55,7 @@ module Renamer = text - let run userSettings workingDirectory (printer: Printer) : unit = + let run (printer: Printer) userSettings workingDirectory : unit = let watch = Watch() let workingDirInfo = DirectoryInfo workingDirectory @@ -73,7 +73,7 @@ module Renamer = let newFileName = userSettings.RenamePatterns |> List.fold - (fun acc -> updateTextViaPattern userSettings.QuietMode printer acc) + (fun acc -> updateTextViaPattern printer userSettings.QuietMode acc) (SB audioFile.Name) |> _.ToString() diff --git a/src/CCVTAC.Main/PostProcessing/Tagging/Tagger.fs b/src/CCVTAC.Main/PostProcessing/Tagging/Tagger.fs index 775a640..bccd6f1 100644 --- a/src/CCVTAC.Main/PostProcessing/Tagging/Tagger.fs +++ b/src/CCVTAC.Main/PostProcessing/Tagging/Tagger.fs @@ -28,7 +28,7 @@ module Tagger = | exn -> Error $"Error reading JSON file \"%s{taggingSet.JsonFile}\": %s{exn.Message}." /// If a video was split into sub-videos, then the original video is unneeded and should be deleted. - let private deleteSourceFile taggingSet (printer: Printer) : TaggingSet = + let private deleteSourceFile (printer: Printer) taggingSet : TaggingSet = if not (List.hasMultiple taggingSet.AudioFiles) then taggingSet else @@ -48,7 +48,7 @@ module Tagger = printer.Error $"Error deleting pre-split source file \"%s{largestFileInfo.Name}\": %s{exn.Message}" taggingSet - let private writeImageToFile (taggedFile: TaggedFile) imageFilePath (printer: Printer) = + let private writeImageToFile (printer: Printer) (taggedFile: TaggedFile) imageFilePath = if String.hasNoText imageFilePath then printer.Error "No image file path was provided, so cannot add an image to the file." else @@ -71,12 +71,12 @@ module Tagger = | _ -> None let private tagSingleFile + (printer: Printer) (settings: UserSettings) (videoData: VideoMetadata) (audioFilePath: string) (imageFilePath: string option) (collectionData: CollectionMetadata option) - (printer: Printer) : unit = let audioFileName = Path.GetFileName audioFilePath @@ -162,7 +162,7 @@ module Tagger = && settings.DoNotEmbedImageUploaders |> List.doesNotContain videoData.Uploader then printer.Debug "Embedding artwork..." - writeImageToFile taggedFile path printer + writeImageToFile printer taggedFile path else printer.Debug "Skipping artwork embedding." | None -> @@ -175,18 +175,18 @@ module Tagger = printer.Error $"Failed to save tags: ${exn.Message}" let private processTaggingSet + (printer: Printer) (settings: UserSettings) (taggingSet: TaggingSet) (collectionJson: CollectionMetadata option) (embedImages: bool) - (printer: Printer) : unit = printer.Debug $"""Found %s{String.fileLabelWithDesc "audio" taggingSet.AudioFiles.Length} with resource ID %s{taggingSet.VideoId}.""" match parseVideoJson taggingSet with | Ok videoData -> - let finalTaggingSet = deleteSourceFile taggingSet printer + let finalTaggingSet = deleteSourceFile printer taggingSet let imagePath = if embedImages && List.isNotEmpty finalTaggingSet.AudioFiles then @@ -196,18 +196,18 @@ module Tagger = for audioPath in finalTaggingSet.AudioFiles do try - tagSingleFile settings videoData audioPath imagePath collectionJson printer + tagSingleFile printer settings videoData audioPath imagePath collectionJson with exn -> printer.Error $"Error tagging file: %s{exn.Message}" | Error err -> printer.Error $"Error deserializing video metadata from \"%s{taggingSet.JsonFile}\": {err}" let run + (printer: Printer) (settings: UserSettings) (taggingSets: TaggingSet seq) (collectionJson: CollectionMetadata option) (mediaType: MediaType) - (printer: Printer) : Result = printer.Debug "Adding file tags..." @@ -216,6 +216,6 @@ module Tagger = let embedImages = settings.EmbedImages && (mediaType.IsVideo || mediaType.IsPlaylistVideo) for taggingSet in taggingSets do - processTaggingSet settings taggingSet collectionJson embedImages printer + processTaggingSet printer settings taggingSet collectionJson embedImages Ok $"Tagging done in %s{watch.ElapsedFriendly}." diff --git a/src/CCVTAC.Main/Program.fs b/src/CCVTAC.Main/Program.fs index 6f78df7..f052786 100644 --- a/src/CCVTAC.Main/Program.fs +++ b/src/CCVTAC.Main/Program.fs @@ -51,7 +51,7 @@ module Program = printer.Error err int ExitCodes.ArgError | Ok settings -> - printSummary settings printer (Some "Settings loaded OK.") + printSummary printer settings (Some "Settings loaded OK.") printer.ShowDebug(not settings.QuietMode) // Catch Ctrl-C (SIGINT) @@ -62,11 +62,11 @@ module Program = | Ok () -> () | Error warnResult -> printer.Error warnResult - match Directories.askToDeleteAllFiles settings.WorkingDirectory printer with + match Directories.askToDeleteAllFiles printer settings.WorkingDirectory with | Error err -> printer.Error err | Ok results -> Directories.printDeletionResults printer results) try - Orchestrator.start settings printer + Orchestrator.start printer settings int ExitCodes.Success with exn -> printer.Critical $"Fatal error: %s{exn.Message}" diff --git a/src/CCVTAC.Main/Settings/Settings.fs b/src/CCVTAC.Main/Settings/Settings.fs index 1388721..5e8e132 100644 --- a/src/CCVTAC.Main/Settings/Settings.fs +++ b/src/CCVTAC.Main/Settings/Settings.fs @@ -112,7 +112,7 @@ module Settings = ("Rename patterns", settings.RenamePatterns.Length |> simplePluralize "pattern") ] - let printSummary settings (printer: Printer) headerOpt : unit = + let printSummary (printer: Printer) settings headerOpt : unit = match headerOpt with | Some h when String.hasText h -> printer.Info h | _ -> () diff --git a/src/CCVTAC.Tests/RenamerTests.fs b/src/CCVTAC.Tests/RenamerTests.fs index 5598e05..e60db6c 100644 --- a/src/CCVTAC.Tests/RenamerTests.fs +++ b/src/CCVTAC.Tests/RenamerTests.fs @@ -36,7 +36,7 @@ module UpdateTextViaPatternsTests = let actual = List.fold - (fun sb pattern -> Renamer.updateTextViaPattern true (Printer false) sb pattern) + (fun sb pattern -> Renamer.updateTextViaPattern (Printer false) true sb pattern) fileName patterns |> _.ToString() From 740c9083ce3adf414decb6070c8a97da958e952c Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sun, 23 Aug 2026 21:34:07 +0900 Subject: [PATCH 25/30] Rewrite main func top logic --- src/CCVTAC.Main/Program.fs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/CCVTAC.Main/Program.fs b/src/CCVTAC.Main/Program.fs index f052786..cab9624 100644 --- a/src/CCVTAC.Main/Program.fs +++ b/src/CCVTAC.Main/Program.fs @@ -26,14 +26,18 @@ module Program = let main args : int = let printer = Printer(showDebug = true) - if Array.isNotEmpty args && Array.containsIgnoreCase args[0] helpFlags then + match args with + | [||] -> printer.Info Help.helpText int ExitCodes.Success - else + | [| arg |] when helpFlags |> Array.containsIgnoreCase arg -> + printer.Info Help.helpText + int ExitCodes.Success + | [| flagArg; settingsFileArg |] -> let settingsPath = FileInfo <| - if Array.hasMultiple args && Array.containsIgnoreCase args[0] settingsFileFlags then - args[1] // Expected to be a settings file path. + if settingsFileFlags |> Array.containsIgnoreCase flagArg then + settingsFileArg else defaultSettingsFileName @@ -73,3 +77,6 @@ module Program = AnsiConsole.WriteException exn printer.Info "Please help improve this tool by reporting this error and any relevant URLs at https://github.com/codeconscious/ccvtac/issues." int ExitCodes.OperationError + | _ -> + printer.Info Help.helpText + int ExitCodes.Success From 2d176007beb3d9a9bde346f8c02a9c044c5f11f7 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Mon, 24 Aug 2026 16:09:19 +0900 Subject: [PATCH 26/30] Rework makeSummary to makeSummaryTable (which is later printed) --- src/CCVTAC.Main/Orchestrator.fs | 2 +- src/CCVTAC.Main/Program.fs | 11 ++++++----- src/CCVTAC.Main/Settings/Settings.fs | 8 ++------ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index a46ed9c..7670b77 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -135,7 +135,7 @@ module Orchestrator = // Settings summary elif checkCommand Commands.settingsSummary then - Settings.printSummary printer settings None + Settings.makeSummaryTable printer settings |> Printer.PrintTable Ok { NextAction = Continue; UpdatedSettings = None } // Toggle split chapters diff --git a/src/CCVTAC.Main/Program.fs b/src/CCVTAC.Main/Program.fs index cab9624..504f361 100644 --- a/src/CCVTAC.Main/Program.fs +++ b/src/CCVTAC.Main/Program.fs @@ -36,10 +36,9 @@ module Program = | [| flagArg; settingsFileArg |] -> let settingsPath = FileInfo <| - if settingsFileFlags |> Array.containsIgnoreCase flagArg then - settingsFileArg - else - defaultSettingsFileName + if settingsFileFlags |> Array.containsIgnoreCase flagArg + then settingsFileArg + else defaultSettingsFileName if not settingsPath.Exists then match writeDefaultFile settingsPath with @@ -55,7 +54,9 @@ module Program = printer.Error err int ExitCodes.ArgError | Ok settings -> - printSummary printer settings (Some "Settings loaded OK.") + printer.Info "Settings loaded OK." + Settings.makeSummaryTable printer settings |> Printer.PrintTable + printer.ShowDebug(not settings.QuietMode) // Catch Ctrl-C (SIGINT) diff --git a/src/CCVTAC.Main/Settings/Settings.fs b/src/CCVTAC.Main/Settings/Settings.fs index 5e8e132..f00f299 100644 --- a/src/CCVTAC.Main/Settings/Settings.fs +++ b/src/CCVTAC.Main/Settings/Settings.fs @@ -112,11 +112,7 @@ module Settings = ("Rename patterns", settings.RenamePatterns.Length |> simplePluralize "pattern") ] - let printSummary (printer: Printer) settings headerOpt : unit = - match headerOpt with - | Some h when String.hasText h -> printer.Info h - | _ -> () - + let makeSummaryTable (printer: Printer) settings : Table = let table = Table() table.Expand() |> ignore table.Border <- TableBorder.HeavyEdge @@ -128,7 +124,7 @@ module Settings = for description, value in summarize settings do table.AddRow(description, value) |> ignore - Printer.PrintTable table + table module Validation' = open System.IO From 765329302bea5fc612ff86c050c32344919a64f3 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Mon, 24 Aug 2026 16:29:03 +0900 Subject: [PATCH 27/30] Make PrintTable instance method --- src/CCVTAC.Main/History.fs | 2 +- src/CCVTAC.Main/Orchestrator.fs | 2 +- src/CCVTAC.Main/Printer.fs | 2 +- src/CCVTAC.Main/Program.fs | 2 +- src/CCVTAC.Main/Settings/Settings.fs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CCVTAC.Main/History.fs b/src/CCVTAC.Main/History.fs index c803126..1f22d48 100644 --- a/src/CCVTAC.Main/History.fs +++ b/src/CCVTAC.Main/History.fs @@ -57,6 +57,6 @@ type History(filePath: string, displayCount: int) = let joinedUrls = String.Join(String.newLine, urls) table.AddRow(formattedTime, joinedUrls) |> ignore - Printer.PrintTable table + printer.PrintTable table with exn -> printer.Error $"Could not display history: %s{exn.Message}" diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index 7670b77..a01c750 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -135,7 +135,7 @@ module Orchestrator = // Settings summary elif checkCommand Commands.settingsSummary then - Settings.makeSummaryTable printer settings |> Printer.PrintTable + Settings.summarizeAsTable settings |> printer.PrintTable Ok { NextAction = Continue; UpdatedSettings = None } // Toggle split chapters diff --git a/src/CCVTAC.Main/Printer.fs b/src/CCVTAC.Main/Printer.fs index a2f68c2..8a4505c 100644 --- a/src/CCVTAC.Main/Printer.fs +++ b/src/CCVTAC.Main/Printer.fs @@ -96,7 +96,7 @@ type Printer(showDebug: bool) = Printer.EmptyLines appendLines - static member PrintTable(table: Table) = + member this.PrintTable(table: Table) = AnsiConsole.Write table member this.Critical(message: string, ?appendLineBreak: bool, ?prependLines: byte, ?appendLines: byte, ?processMarkup: bool) = diff --git a/src/CCVTAC.Main/Program.fs b/src/CCVTAC.Main/Program.fs index 504f361..f9cfc85 100644 --- a/src/CCVTAC.Main/Program.fs +++ b/src/CCVTAC.Main/Program.fs @@ -55,7 +55,7 @@ module Program = int ExitCodes.ArgError | Ok settings -> printer.Info "Settings loaded OK." - Settings.makeSummaryTable printer settings |> Printer.PrintTable + Settings.summarizeAsTable settings |> printer.PrintTable printer.ShowDebug(not settings.QuietMode) diff --git a/src/CCVTAC.Main/Settings/Settings.fs b/src/CCVTAC.Main/Settings/Settings.fs index f00f299..e5ad341 100644 --- a/src/CCVTAC.Main/Settings/Settings.fs +++ b/src/CCVTAC.Main/Settings/Settings.fs @@ -112,7 +112,7 @@ module Settings = ("Rename patterns", settings.RenamePatterns.Length |> simplePluralize "pattern") ] - let makeSummaryTable (printer: Printer) settings : Table = + let summarizeAsTable settings : Table = let table = Table() table.Expand() |> ignore table.Border <- TableBorder.HeavyEdge From 97dec9ae16e5703a9c221b5fb4fb21ba0a379fd1 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Mon, 24 Aug 2026 18:20:03 +0900 Subject: [PATCH 28/30] Use nl over newLine --- src/CCVTAC.Main/History.fs | 4 ++-- src/CCVTAC.Main/IoUtilities/Directories.fs | 5 ++--- src/CCVTAC.Main/Orchestrator.fs | 2 +- src/CCVTAC.Main/PostProcessing/MetadataUtilities.fs | 4 ++-- src/CCVTAC.Main/PostProcessing/PostProcessing.fs | 2 +- src/CCVTAC.Main/PostProcessing/Tagging/Tagger.fs | 2 +- src/CCVTAC.Main/Printer.fs | 2 +- src/CCVTAC.Main/Program.fs | 4 ++-- src/CCVTAC.Main/Settings/Settings.fs | 4 ++-- src/CCVTAC.Tests/PostProcessing/Tagging/TagDetectionTests.fs | 2 +- src/CCVTAC.Tests/RenamerTests.fs | 4 ++-- 11 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/CCVTAC.Main/History.fs b/src/CCVTAC.Main/History.fs index 1f22d48..d16c6cf 100644 --- a/src/CCVTAC.Main/History.fs +++ b/src/CCVTAC.Main/History.fs @@ -19,7 +19,7 @@ type History(filePath: string, displayCount: int) = member this.Append(url: string, entryTime: DateTime, printer: Printer) : unit = try let serializedTime = JsonSerializer.Serialize(entryTime).Replace("\"", "") - let text = serializedTime + string separator + url + String.newLine + let text = serializedTime + string separator + url + String.nl match appendToFile this.FileInfo text with | Ok _ -> printer.Debug $"Added \"%s{url}\" to the history log." @@ -54,7 +54,7 @@ type History(filePath: string, displayCount: int) = for dateTime, urls in historyData do let formattedTime = sprintf "%s" (dateTime.ToString("yyyy-MM-dd HH:mm:ss")) - let joinedUrls = String.Join(String.newLine, urls) + let joinedUrls = String.Join(String.nl, urls) table.AddRow(formattedTime, joinedUrls) |> ignore printer.PrintTable table diff --git a/src/CCVTAC.Main/IoUtilities/Directories.fs b/src/CCVTAC.Main/IoUtilities/Directories.fs index aab42f1..c5811a4 100644 --- a/src/CCVTAC.Main/IoUtilities/Directories.fs +++ b/src/CCVTAC.Main/IoUtilities/Directories.fs @@ -5,7 +5,6 @@ open CCFSharpUtils open CCFSharpUtils.Collections open CCFSharpUtils.Text open System.IO -open System.Text module Directories = @@ -68,12 +67,12 @@ module Directories = if Array.isEmpty fileNames then Ok () else - StringBuilder($"Unexpectedly found {String.fileLabel fileNames.Length} in working directory \"{dirName}\":{String.newLine}") + SB($"Unexpectedly found {String.fileLabel fileNames.Length} in working directory \"{dirName}\":{String.nl}") .AppendLine (fileNames |> Array.truncate showMax |> Array.map (sprintf "• %s") - |> String.concat String.newLine) + |> String.concat String.nl) |> fun sb -> if fileNames.Length > showMax then sb.AppendLine $"... plus {fileNames.Length - showMax} more." diff --git a/src/CCVTAC.Main/Orchestrator.fs b/src/CCVTAC.Main/Orchestrator.fs index a01c750..b4b52ac 100644 --- a/src/CCVTAC.Main/Orchestrator.fs +++ b/src/CCVTAC.Main/Orchestrator.fs @@ -135,7 +135,7 @@ module Orchestrator = // Settings summary elif checkCommand Commands.settingsSummary then - Settings.summarizeAsTable settings |> printer.PrintTable + Settings.toTable settings |> printer.PrintTable Ok { NextAction = Continue; UpdatedSettings = None } // Toggle split chapters diff --git a/src/CCVTAC.Main/PostProcessing/MetadataUtilities.fs b/src/CCVTAC.Main/PostProcessing/MetadataUtilities.fs index 37174e8..9ecbae5 100644 --- a/src/CCVTAC.Main/PostProcessing/MetadataUtilities.fs +++ b/src/CCVTAC.Main/PostProcessing/MetadataUtilities.fs @@ -1,8 +1,8 @@ namespace CCVTAC.Main.PostProcessing +open CCFSharpUtils open CCFSharpUtils.Text open System -open System.Text module MetadataUtilities = @@ -20,7 +20,7 @@ module MetadataUtilities = sprintf "%s/%s/%s" m d y let generateComment (v: VideoMetadata) (c: CollectionMetadata option) : string = - let sb = StringBuilder() + let sb = SB() sb.AppendLine("CCVTAC SOURCE DATA:") |> ignore sb.AppendLine $"■ Downloaded: {DateTime.Now}" |> ignore sb.AppendLine $"■ URL: %s{v.WebpageUrl}" |> ignore diff --git a/src/CCVTAC.Main/PostProcessing/PostProcessing.fs b/src/CCVTAC.Main/PostProcessing/PostProcessing.fs index 12aba50..2f041e4 100644 --- a/src/CCVTAC.Main/PostProcessing/PostProcessing.fs +++ b/src/CCVTAC.Main/PostProcessing/PostProcessing.fs @@ -48,7 +48,7 @@ module PostProcessor = | Ok ts -> Ok ts | Error msgs -> $"Error(s) creating tagging sets in working directory \"%s{dir}\"" :: msgs - |> String.concat String.newLine + |> String.concat String.nl |> Error with exn -> Error $"Error reading working files in \"{dir}\" for tagging set creation: %s{exn.Message}" diff --git a/src/CCVTAC.Main/PostProcessing/Tagging/Tagger.fs b/src/CCVTAC.Main/PostProcessing/Tagging/Tagger.fs index bccd6f1..ee29f1a 100644 --- a/src/CCVTAC.Main/PostProcessing/Tagging/Tagger.fs +++ b/src/CCVTAC.Main/PostProcessing/Tagging/Tagger.fs @@ -24,7 +24,7 @@ module Tagger = | Null -> Error $"Deserialized JSON was null for \"%s{taggingSet.JsonFile}\"." | NonNull v -> Ok v with - | :? JsonException as exn -> Error $"%s{exn.Message}%s{String.newLine}%s{exn.StackTrace}" + | :? JsonException as exn -> Error $"%s{exn.Message}%s{String.nl}%s{exn.StackTrace}" | exn -> Error $"Error reading JSON file \"%s{taggingSet.JsonFile}\": %s{exn.Message}." /// If a video was split into sub-videos, then the original video is unneeded and should be deleted. diff --git a/src/CCVTAC.Main/Printer.fs b/src/CCVTAC.Main/Printer.fs index 8a4505c..f52fafb 100644 --- a/src/CCVTAC.Main/Printer.fs +++ b/src/CCVTAC.Main/Printer.fs @@ -147,7 +147,7 @@ type Printer(showDebug: bool) = let repeats = int count - 1 if repeats < 1 then AnsiConsole.WriteLine() - else Enumerable.Repeat(String.newLine, repeats) + else Enumerable.Repeat(String.nl, repeats) |> String.Concat |> AnsiConsole.WriteLine diff --git a/src/CCVTAC.Main/Program.fs b/src/CCVTAC.Main/Program.fs index f9cfc85..f6bdb94 100644 --- a/src/CCVTAC.Main/Program.fs +++ b/src/CCVTAC.Main/Program.fs @@ -55,13 +55,13 @@ module Program = int ExitCodes.ArgError | Ok settings -> printer.Info "Settings loaded OK." - Settings.summarizeAsTable settings |> printer.PrintTable + Settings.toTable settings |> printer.PrintTable printer.ShowDebug(not settings.QuietMode) // Catch Ctrl-C (SIGINT) Console.CancelKeyPress.Add(fun _ -> - printer.Warning($"{String.newLine}Quitting at user's request.") + printer.Warning($"{String.nl}Quitting at user's request.") match Directories.warnIfAnyFiles 10 settings.WorkingDirectory with | Ok () -> () diff --git a/src/CCVTAC.Main/Settings/Settings.fs b/src/CCVTAC.Main/Settings/Settings.fs index e5ad341..5327b2d 100644 --- a/src/CCVTAC.Main/Settings/Settings.fs +++ b/src/CCVTAC.Main/Settings/Settings.fs @@ -112,7 +112,7 @@ module Settings = ("Rename patterns", settings.RenamePatterns.Length |> simplePluralize "pattern") ] - let summarizeAsTable settings : Table = + let toTable settings : Table = let table = Table() table.Expand() |> ignore table.Border <- TableBorder.HeavyEdge @@ -155,7 +155,7 @@ module Settings = | { AudioFormats = fmt } when not (fmt |> List.forall validAudioFormat) -> let formats = String.Join(", ", fmt) let approved = supportedAudioFormats |> String.concat ", " - Error $"Audio formats (\"%s{formats}\") include an unsupported audio format.{String.newLine}Only the following supported formats: {approved}." + Error $"Audio formats (\"%s{formats}\") include an unsupported audio format.{String.nl}Only the following supported formats: {approved}." | _ -> Ok settings diff --git a/src/CCVTAC.Tests/PostProcessing/Tagging/TagDetectionTests.fs b/src/CCVTAC.Tests/PostProcessing/Tagging/TagDetectionTests.fs index 6159704..05ce70e 100644 --- a/src/CCVTAC.Tests/PostProcessing/Tagging/TagDetectionTests.fs +++ b/src/CCVTAC.Tests/PostProcessing/Tagging/TagDetectionTests.fs @@ -82,7 +82,7 @@ let emptyVideoMetadata = { Type = String.Empty } -let newLine = String.newLine +let newLine = String.nl [] let ``Tag detection patterns detect metadata in video metadata`` () = diff --git a/src/CCVTAC.Tests/RenamerTests.fs b/src/CCVTAC.Tests/RenamerTests.fs index e60db6c..a2346f0 100644 --- a/src/CCVTAC.Tests/RenamerTests.fs +++ b/src/CCVTAC.Tests/RenamerTests.fs @@ -3,8 +3,8 @@ module RenamerTests open CCVTAC.Main open CCVTAC.Main.Settings.Settings open CCVTAC.Main.PostProcessing +open CCFSharpUtils open System -open System.Text open Xunit module UpdateTextViaPatternsTests = @@ -30,7 +30,7 @@ module UpdateTextViaPatternsTests = Summary = "Remove trailing spaces before the file extension" } ] - let fileName = StringBuilder "ARTIST「TITLE」(1923)    (字幕) [5B1rB894B1U].m4a" + let fileName = SB "ARTIST「TITLE」(1923)    (字幕) [5B1rB894B1U].m4a" let expected = "ARTIST - TITLE [1923].m4a" From fc78df9b2fe65f50463194f962ef2758ef3a2ce0 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Tue, 25 Aug 2026 17:43:40 +0900 Subject: [PATCH 29/30] Last minor cleanup --- src/CCVTAC.Main/PostProcessing/Tagging/Tagger.fs | 2 +- src/CCVTAC.Main/Program.fs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/CCVTAC.Main/PostProcessing/Tagging/Tagger.fs b/src/CCVTAC.Main/PostProcessing/Tagging/Tagger.fs index ee29f1a..e1dba8d 100644 --- a/src/CCVTAC.Main/PostProcessing/Tagging/Tagger.fs +++ b/src/CCVTAC.Main/PostProcessing/Tagging/Tagger.fs @@ -28,7 +28,7 @@ module Tagger = | exn -> Error $"Error reading JSON file \"%s{taggingSet.JsonFile}\": %s{exn.Message}." /// If a video was split into sub-videos, then the original video is unneeded and should be deleted. - let private deleteSourceFile (printer: Printer) taggingSet : TaggingSet = + let private deleteSourceFile (printer: Printer) taggingSet : TaggingSet = if not (List.hasMultiple taggingSet.AudioFiles) then taggingSet else diff --git a/src/CCVTAC.Main/Program.fs b/src/CCVTAC.Main/Program.fs index f6bdb94..63cc8c9 100644 --- a/src/CCVTAC.Main/Program.fs +++ b/src/CCVTAC.Main/Program.fs @@ -55,7 +55,7 @@ module Program = int ExitCodes.ArgError | Ok settings -> printer.Info "Settings loaded OK." - Settings.toTable settings |> printer.PrintTable + settings |> toTable |> printer.PrintTable printer.ShowDebug(not settings.QuietMode) @@ -68,7 +68,7 @@ module Program = | Error warnResult -> printer.Error warnResult match Directories.askToDeleteAllFiles printer settings.WorkingDirectory with - | Error err -> printer.Error err + | Error err -> printer.Error err | Ok results -> Directories.printDeletionResults printer results) try Orchestrator.start printer settings From 64f48f1ae5d8dff806466c4d2c87e13816f27520 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Tue, 25 Aug 2026 20:49:45 +0900 Subject: [PATCH 30/30] Remove unneeded variable --- src/CCVTAC.Tests/PostProcessing/Tagging/TagDetectionTests.fs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/CCVTAC.Tests/PostProcessing/Tagging/TagDetectionTests.fs b/src/CCVTAC.Tests/PostProcessing/Tagging/TagDetectionTests.fs index 05ce70e..9da59db 100644 --- a/src/CCVTAC.Tests/PostProcessing/Tagging/TagDetectionTests.fs +++ b/src/CCVTAC.Tests/PostProcessing/Tagging/TagDetectionTests.fs @@ -82,8 +82,6 @@ let emptyVideoMetadata = { Type = String.Empty } -let newLine = String.nl - [] let ``Tag detection patterns detect metadata in video metadata`` () = let testArtist = "Test Artist Name (日本語入り)" @@ -95,7 +93,7 @@ let ``Tag detection patterns detect metadata in video metadata`` () = let videoMetadata = { emptyVideoMetadata with Title = $"{testArtist}「{testTitle}」" - Description = $"album: {testAlbum}{newLine}℗ %d{testYear}{newLine}Composed by: {testComposer}" } + Description = $"album: {testAlbum}{String.nl}℗ %d{testYear}{String.nl}Composed by: {testComposer}" } let artistPattern = { RegexPattern = "^(.+?)「(.+)」"