From 44a570db7a3402273a0f9cf50143f4a12e432981 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Fri, 10 Jul 2026 20:51:57 +0900 Subject: [PATCH 1/5] Initial test version --- src/CCVTAC.Main/Downloading/Downloader.fs | 79 ++++++++++++----------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/src/CCVTAC.Main/Downloading/Downloader.fs b/src/CCVTAC.Main/Downloading/Downloader.fs index ba44373..1b83fe1 100644 --- a/src/CCVTAC.Main/Downloading/Downloader.fs +++ b/src/CCVTAC.Main/Downloading/Downloader.fs @@ -69,43 +69,50 @@ module Downloader = let downloadMedia (printer: Printer) (mediaType: MediaType) userSettings (PrimaryUrl url) : Result = + let maximumAttempts = 3 + if not mediaType.IsVideo && not mediaType.IsPlaylistVideo then - printer.Info("Please wait for multiple videos to be downloaded...") - - let rec loop errors audioFormats = - match audioFormats with - | [] -> - Error errors - | format :: formats -> - let args = generateDownloadArgs (Some format) userSettings (Some mediaType) (Some [url]) - let commandWithArgs = $"{programName} {args}" - let downloadSettings = ToolSettings.create commandWithArgs userSettings.WorkingDirectory - - let downloadResult = runTool downloadSettings [1] printer - let filesDownloaded = audioFileCount userSettings.WorkingDirectory Files.audioFileExts > 0 - - match downloadResult, filesDownloaded with - | Ok result, true -> - Ok <| - $"Successfully downloaded the \"{format}\" format." - :: match result.Error with - | Some err -> [$"However, a minor issue was reported: {err}"] - | None -> [] - | Ok result, false -> - Error <| - $"The \"{format}\" format download was reported as successful, but no audio files were downloaded!" - :: match result.Error with - | Some err -> [err] - | None -> [] - | Error err, true -> - Error <| - [$"The downloader reported failure for \"{format}\", yet audio files were unexpectedly downloaded!" - 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 - - loop [] userSettings.AudioFormats + printer.Info "Please wait for multiple videos to be downloaded..." + + let rec loop errors attemptsRemaining audioFormats = + if attemptsRemaining = 0 then + Error (List.append errors [$"Gave up after {maximumAttempts} attempts."]) + else + match audioFormats with + | [] -> + Error errors + | format :: formats -> + let args = generateDownloadArgs (Some format) userSettings (Some mediaType) (Some [url]) + let commandWithArgs = $"{programName} {args}" + let downloadSettings = ToolSettings.create commandWithArgs userSettings.WorkingDirectory + + let downloadResult = runTool downloadSettings [1] printer + let filesDownloaded = audioFileCount userSettings.WorkingDirectory Files.audioFileExts > 0 + + match downloadResult, filesDownloaded with + | Ok result, true -> + Ok <| + $"Successfully downloaded the \"{format}\" format." + :: match result.Error with + | Some err -> [$"However, a minor issue was reported: {err}"] + | None -> [] + | Ok result, false -> + let newErr = + $"The \"{format}\" format download was reported as successful, but no audio files were downloaded!" + :: match result.Error with + | Some err -> [err] + | None -> [] + loop (List.append errors newErr) (attemptsRemaining - 1) formats + | Error err, true -> + let newErr = + [$"The downloader reported failure for \"{format}\", yet audio files were unexpectedly downloaded!" + err] + loop (List.append errors newErr) (attemptsRemaining - 1) formats + | 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) (attemptsRemaining - 1) formats + + loop [] maximumAttempts userSettings.AudioFormats let downloadMetadata (printer: Printer) userSettings (SupplementaryUrl url) : Result = match url with From 07736121349afb2c18b5ecd5d0f72d0478375deb Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 11 Jul 2026 15:57:25 +0900 Subject: [PATCH 2/5] Add more logging --- src/CCVTAC.Main/Downloading/Downloader.fs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/CCVTAC.Main/Downloading/Downloader.fs b/src/CCVTAC.Main/Downloading/Downloader.fs index 1b83fe1..56c335c 100644 --- a/src/CCVTAC.Main/Downloading/Downloader.fs +++ b/src/CCVTAC.Main/Downloading/Downloader.fs @@ -7,6 +7,7 @@ open CCVTAC.Main.IoUtilities.Directories open CCVTAC.Main.Downloading.Downloading open CCVTAC.Main.ExternalTools open CCVTAC.Main.Settings.Settings +open CCFSharpUtils.Text open FsToolkit.ErrorHandling open System @@ -76,8 +77,11 @@ module Downloader = let rec loop errors attemptsRemaining audioFormats = if attemptsRemaining = 0 then - Error (List.append errors [$"Gave up after {maximumAttempts} attempts."]) + Error (List.append errors [$"Gave up after {maximumAttempts} failed attempts."]) else + if attemptsRemaining < maximumAttempts then + printfn $"""{String.pluralizeSWithCount "attempt" attemptsRemaining} remaining...""" + match audioFormats with | [] -> Error errors From 6c73ba583cee4c959d675177fafc5d60fde55df4 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Sat, 18 Jul 2026 10:17:20 +0900 Subject: [PATCH 3/5] Update error message --- src/CCVTAC.Main/Downloading/Downloader.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CCVTAC.Main/Downloading/Downloader.fs b/src/CCVTAC.Main/Downloading/Downloader.fs index 56c335c..a1ec864 100644 --- a/src/CCVTAC.Main/Downloading/Downloader.fs +++ b/src/CCVTAC.Main/Downloading/Downloader.fs @@ -102,7 +102,7 @@ module Downloader = | None -> [] | Ok result, false -> let newErr = - $"The \"{format}\" format download was reported as successful, but no audio files were downloaded!" + $"While the downloader finished successfully, no audio files were downloaded the \"{format}\" format." :: match result.Error with | Some err -> [err] | None -> [] From e7fe4b309a1dd699532eb36dfcdc108343bb5250 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Mon, 20 Jul 2026 10:35:19 +0900 Subject: [PATCH 4/5] Fix attempt counting --- src/CCVTAC.Main/Downloading/Downloader.fs | 35 ++++++++++++----------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/CCVTAC.Main/Downloading/Downloader.fs b/src/CCVTAC.Main/Downloading/Downloader.fs index a1ec864..80dc0d7 100644 --- a/src/CCVTAC.Main/Downloading/Downloader.fs +++ b/src/CCVTAC.Main/Downloading/Downloader.fs @@ -76,15 +76,10 @@ module Downloader = printer.Info "Please wait for multiple videos to be downloaded..." let rec loop errors attemptsRemaining audioFormats = - if attemptsRemaining = 0 then - Error (List.append errors [$"Gave up after {maximumAttempts} failed attempts."]) - else - if attemptsRemaining < maximumAttempts then - printfn $"""{String.pluralizeSWithCount "attempt" attemptsRemaining} remaining...""" - - match audioFormats with + let rec attemptLoop errors attemptsRemaining remainingAudioFormats = + match remainingAudioFormats with | [] -> - Error errors + loop errors (attemptsRemaining - 1) audioFormats | format :: formats -> let args = generateDownloadArgs (Some format) userSettings (Some mediaType) (Some [url]) let commandWithArgs = $"{programName} {args}" @@ -100,21 +95,29 @@ module Downloader = :: match result.Error with | Some err -> [$"However, a minor issue was reported: {err}"] | None -> [] - | Ok result, false -> + | Ok result, _ -> let newErr = - $"While the downloader finished successfully, no audio files were downloaded the \"{format}\" format." - :: match result.Error with - | Some err -> [err] - | None -> [] - loop (List.append errors newErr) (attemptsRemaining - 1) formats + $"While the downloader finished successfully, no audio files were downloaded the \"{format}\" format." + :: match result.Error with + | Some err -> [err] + | None -> [] + attemptLoop (List.append errors newErr) attemptsRemaining formats | Error err, true -> let newErr = [$"The downloader reported failure for \"{format}\", yet audio files were unexpectedly downloaded!" err] - loop (List.append errors newErr) (attemptsRemaining - 1) formats + attemptLoop (List.append errors newErr) attemptsRemaining formats | 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) (attemptsRemaining - 1) formats + attemptLoop (List.append errors newErr) attemptsRemaining formats + + if attemptsRemaining = 0 then + Error (List.append errors [$"Gave up after {maximumAttempts} failed attempts."]) + else + if attemptsRemaining < maximumAttempts then + printfn $"""{String.pluralizeSWithCount "attempt" attemptsRemaining} remaining...""" + + attemptLoop errors attemptsRemaining audioFormats loop [] maximumAttempts userSettings.AudioFormats From 8151abc96155d6bd37feaba9471caa9e16919097 Mon Sep 17 00:00:00 2001 From: CodeConscious <50596087+codeconscious@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:34:39 +0900 Subject: [PATCH 5/5] Refactor downloadMedia [AI] --- src/CCVTAC.Main/Downloading/Downloader.fs | 86 +++++++++++------------ 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/src/CCVTAC.Main/Downloading/Downloader.fs b/src/CCVTAC.Main/Downloading/Downloader.fs index 80dc0d7..8b65a48 100644 --- a/src/CCVTAC.Main/Downloading/Downloader.fs +++ b/src/CCVTAC.Main/Downloading/Downloader.fs @@ -7,6 +7,7 @@ open CCVTAC.Main.IoUtilities.Directories open CCVTAC.Main.Downloading.Downloading open CCVTAC.Main.ExternalTools open CCVTAC.Main.Settings.Settings +open CCFSharpUtils open CCFSharpUtils.Text open FsToolkit.ErrorHandling open System @@ -70,56 +71,55 @@ module Downloader = let downloadMedia (printer: Printer) (mediaType: MediaType) userSettings (PrimaryUrl url) : Result = + // One attempt refers to a set of attempted downloads for all audio formats. let maximumAttempts = 3 if not mediaType.IsVideo && not mediaType.IsPlaylistVideo then printer.Info "Please wait for multiple videos to be downloaded..." - let rec loop errors attemptsRemaining audioFormats = - let rec attemptLoop errors attemptsRemaining remainingAudioFormats = - match remainingAudioFormats with - | [] -> - loop errors (attemptsRemaining - 1) audioFormats - | format :: formats -> - let args = generateDownloadArgs (Some format) userSettings (Some mediaType) (Some [url]) - let commandWithArgs = $"{programName} {args}" - let downloadSettings = ToolSettings.create commandWithArgs userSettings.WorkingDirectory - - let downloadResult = runTool downloadSettings [1] printer - let filesDownloaded = audioFileCount userSettings.WorkingDirectory Files.audioFileExts > 0 - - match downloadResult, filesDownloaded with - | Ok result, true -> - Ok <| - $"Successfully downloaded the \"{format}\" format." - :: match result.Error with - | Some err -> [$"However, a minor issue was reported: {err}"] - | None -> [] - | Ok result, _ -> - let newErr = - $"While the downloader finished successfully, no audio files were downloaded the \"{format}\" format." - :: match result.Error with - | Some err -> [err] - | None -> [] - attemptLoop (List.append errors newErr) attemptsRemaining formats - | Error err, true -> - let newErr = - [$"The downloader reported failure for \"{format}\", yet audio files were unexpectedly downloaded!" - err] - attemptLoop (List.append errors newErr) attemptsRemaining formats - | Error err, false -> - let newErr = [$"A download error was reported for the \"{format}\" format, and no audio files were downloaded. {err}"] - attemptLoop (List.append errors newErr) attemptsRemaining formats - - if attemptsRemaining = 0 then - Error (List.append errors [$"Gave up after {maximumAttempts} failed attempts."]) - else - if attemptsRemaining < maximumAttempts then - printfn $"""{String.pluralizeSWithCount "attempt" attemptsRemaining} remaining...""" + let buildErrorMessage mainMsg maybeErr = + match maybeErr with + | Some err -> [mainMsg; err] + | None -> [mainMsg] - attemptLoop errors attemptsRemaining audioFormats + let attemptAudioFormat format errors = + let args = generateDownloadArgs (Some format) userSettings (Some mediaType) (Some [url]) + let commandWithArgs = $"{programName} {args}" + let downloadSettings = ToolSettings.create commandWithArgs userSettings.WorkingDirectory - loop [] maximumAttempts userSettings.AudioFormats + let downloadResult = runTool downloadSettings [1] printer + let anyFilesDownloaded = Num.isPos <| audioFileCount userSettings.WorkingDirectory Files.audioFileExts + + match downloadResult, anyFilesDownloaded with + | Ok result, true -> + Ok ( + $"Successfully downloaded the \"{format}\" format." + :: match result.Error with Some err -> [$"However, a minor issue was reported: {err}"] | None -> [] + ) + | Ok result, false -> + let msg = $"While the downloader finished successfully, no audio files were downloaded in the \"{format}\" format." + Error (errors @ buildErrorMessage msg result.Error) + | Error err, true -> + let msg = $"The downloader reported failure for \"{format}\", yet audio files were unexpectedly downloaded!" + Error (errors @ buildErrorMessage msg (Some err)) + | Error err, false -> + let msg = $"A download error was reported for the \"{format}\" format, and no audio files were downloaded. {err}" + Error (errors @ [msg]) + + let rec retryLoop errors attemptsRemaining audioFormats = + if Num.isZero attemptsRemaining then + Error (errors @ [$"Gave up after {maximumAttempts} failed attempts."]) + else + match audioFormats with + | [] -> + // All formats attempted, retry with full list + retryLoop errors (attemptsRemaining - 1) userSettings.AudioFormats + | format :: remainingFormats -> + match attemptAudioFormat format errors with + | Ok msgs -> Ok msgs + | Error errs -> retryLoop errs attemptsRemaining remainingFormats + + retryLoop [] maximumAttempts userSettings.AudioFormats let downloadMetadata (printer: Printer) userSettings (SupplementaryUrl url) : Result = match url with