Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
3ca20b9
Add EmptyLines method to Printer
codeconscious Aug 15, 2026
edaf3f5
Remove superfluous type names
codeconscious Aug 15, 2026
40f6e58
Fix incorrect input counts
codeconscious Aug 15, 2026
c1a0acf
Print empty line on error too
codeconscious Aug 15, 2026
b23c4cb
Combine warnings into one message
codeconscious Aug 15, 2026
e408728
Convert Result return to unit
codeconscious Aug 15, 2026
adb9b79
Minor code tweak
codeconscious Aug 15, 2026
857b668
Add EmptyLine() method to Printer
codeconscious Aug 15, 2026
5deaf03
Remove superfluous type name
codeconscious Aug 15, 2026
1fd5ad7
Remove superfluous type name
codeconscious Aug 15, 2026
4fb819a
Use EmptyLine()
codeconscious Aug 15, 2026
8a7ab70
Rename ResultMessageCollection to ResultMessages
codeconscious Aug 15, 2026
704018d
Change retries from 2 to 3
codeconscious Aug 15, 2026
c20ed8c
Show warnings after successful download
codeconscious Aug 18, 2026
091835d
Delete leftover files after download failure (Fixes regression)
codeconscious Aug 18, 2026
9a2f372
Return error without printing
codeconscious Aug 19, 2026
a4b55d5
Return confirmation message upon successful deletion
codeconscious Aug 19, 2026
0d0c5dc
Rename variable
codeconscious Aug 19, 2026
e02dafd
Refactor deleteAllFiles func
codeconscious Aug 19, 2026
05d56e0
Convert array to list
codeconscious Aug 19, 2026
17a5b18
Nomenclature
codeconscious Aug 19, 2026
17d4263
Change seq to list
codeconscious Aug 19, 2026
2498371
Mild tweaks
codeconscious Aug 20, 2026
fbc2912
Make printer args first
codeconscious Aug 22, 2026
740c908
Rewrite main func top logic
codeconscious Aug 23, 2026
2d17600
Rework makeSummary to makeSummaryTable (which is later printed)
codeconscious Aug 24, 2026
7653293
Make PrintTable instance method
codeconscious Aug 24, 2026
97dec9a
Use nl over newLine
codeconscious Aug 24, 2026
fc78df9
Last minor cleanup
codeconscious Aug 25, 2026
64f48f1
Remove unneeded variable
codeconscious Aug 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/CCVTAC.Main/Downloading/Downloader.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -37,7 +36,7 @@ module Downloader =
"--write-thumbnail --convert-thumbnails jpg"
writeJsonArg
trimFileNamesArg
"--retries 2" ]
"--retries 3" ]
|> Set.ofList

if userSettings.QuietMode then
Expand Down Expand Up @@ -87,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
Expand Down Expand Up @@ -128,19 +127,20 @@ 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<string, string list> =
let run (printer: Printer) (mediaType: MediaType) userSettings : Result<string, string list> =
result {
let rawUrls = generateDownloadUrl mediaType
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
}
34 changes: 17 additions & 17 deletions src/CCVTAC.Main/Downloading/Updater.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@ open CCFSharpUtils.Text

module Updater =

let run userSettings (printer: Printer) : Result<unit, string> =
let successExitCode = 0

let run (printer: Printer) userSettings : unit =
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."
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.")

match result.Error with
| Some w -> printer.Warning w
| None -> ()
let toolSettings = ToolSettings.create userSettings.DownloaderUpdateCommand
userSettings.WorkingDirectory

Ok()
let executionResult = Runner.runTool printer toolSettings []

| Error err ->
printer.Error $"Failure updating: {err}"
Error err
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.EmptyLine()
| Error msg ->
printer.Error($"Failure updating: {msg}", ?appendLines = Some 1uy)
2 changes: 1 addition & 1 deletion src/CCVTAC.Main/ExternalTools/Runner.fs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module Runner =
/// <param name="settings">Tool settings for execution</param>
/// <param name="otherSuccessExitCodes">Additional exit codes, other than 0, that can be treated as non-failures</param>
/// <param name="printer"></param>
let runTool toolSettings otherSuccessExitCodes (printer: Printer) : Result<ToolResult, string> =
let runTool (printer: Printer) toolSettings otherSuccessExitCodes : Result<ToolResult, string> =
let watch = Watch()
printer.Info $"Running {toolSettings.CommandWithArgs}..."

Expand Down
6 changes: 3 additions & 3 deletions src/CCVTAC.Main/History.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down Expand Up @@ -54,9 +54,9 @@ 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
printer.PrintTable table
with exn ->
printer.Error $"Could not display history: %s{exn.Message}"
50 changes: 21 additions & 29 deletions src/CCVTAC.Main/IoUtilities/Directories.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,31 @@ open CCFSharpUtils
open CCFSharpUtils.Collections
open CCFSharpUtils.Text
open System.IO
open System.Text

module Directories =

[<Literal>]
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)
: Result<string array, string> =

let ignoreFiles =
customIgnoreFiles
|> Option.defaultValue Seq.empty
let private getDirectoryFileNames dirName ignoreFilesOpt : Result<string array, string> =
let ignoreFiles : string list =
ignoreFilesOpt
|> Option.defaultValue List.empty
|> Seq.distinct
|> Seq.toArray
|> Seq.toList

ofTry (fun _ ->
Directory.GetFiles(directoryName, allFilesSearchPattern, EnumerationOptions())
|> Array.filter (fun filePath -> not (ignoreFiles |> Array.exists filePath.EndsWith)))

let deleteAllFiles workingDirectory
: Result<ResultMessageCollection, string> =
Directory.GetFiles(dirName, allFilesSearchPattern, EnumerationOptions())
|> Array.filter (fun filePath -> not (ignoreFiles |> List.exists filePath.EndsWith)))

let deleteAllFiles workingDirectory : Result<ResultMessages, string> =
let delete fileNames =
let successes, failures = ResizeArray<string>(), ResizeArray<string>()

Expand All @@ -47,45 +40,44 @@ 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) =
let askToDeleteAllFiles (printer: Printer) dirName =
if printer.AskToBool("Delete all temporary files?", "Yes", "No")
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

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 =
let warnIfAnyFiles showMax dirName : Result<unit, string> =
match getDirectoryFileNames dirName None with
| Error errMsg -> Error errMsg
| Ok fileNames ->
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."
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

Expand Down
Loading