Skip to content

Instantly share code, notes, and snippets.

@jkone27
Last active January 20, 2025 12:38
Show Gist options
  • Save jkone27/91ab74a87ef64ae14a2ddf7ea3fdbd38 to your computer and use it in GitHub Desktop.
Save jkone27/91ab74a87ef64ae14a2ddf7ea3fdbd38 to your computer and use it in GitHub Desktop.
spectre console F# SpectreCoff HTTP file download with progress bar
#r "nuget: EluciusFTW.SpectreCoff, 0.49.12"
open System
open System.IO
open System.Net.Http
open System.Threading.Tasks
open SpectreCoff.Progress
open SpectreCoff
// Function to download a file with a progress bar
let downloadFileWithProgress (destinationPath: string) (url: string) context =
task {
let client = new HttpClient()
let! response =
client.GetAsync(
url,
HttpCompletionOption.ResponseHeadersRead)
let totalBytes =
response.Content.Headers.ContentLength.Value
let buffer =
Array.zeroCreate<byte> 8192
use! stream = response.Content.ReadAsStreamAsync()
use fileStream =
new FileStream(
destinationPath,
FileMode.Create,
FileAccess.Write,
FileShare.None)
"Downloading: "
|> Pumped
|> toConsole
url
|> SpectreCoff.Output.Link
|> toConsole
// Initialize the progress bar
let downloadProgress =
$"Downloading:"
|> HotPercentageTask
|> realizeIn context
let mutable bytesDownloaded = 0L
let mutable isComplete = false
while bytesDownloaded < totalBytes && not isComplete do
let bytesRead = stream.Read(buffer, 0, buffer.Length)
if bytesRead > 0 then
fileStream.Write(buffer, 0, bytesRead)
bytesDownloaded <- bytesDownloaded + int64 bytesRead
// Update progress bar
downloadProgress
|> incrementBy (float bytesRead / float totalBytes * 100.0)
|> ignore
else
isComplete <- true
// refres interval
do! Task.Delay(TimeSpan.FromMilliseconds(300))
// Mark download as complete
BulletItems [
$"Downloaded: {bytesDownloaded} bytes" |> Calm
$"vscode://file{destinationPath |> Path.GetFullPath}" |> Output.Link
]
|> toConsole
}
// Example usage
let template =
emptyTemplate
|> withDescriptionColumn
|> withSpinnerColumn
|> withRemainingTimeColumn
|> withProgressBarColumn
// Start download with progress tracking
"https://raw.githubusercontent.com/observablehq/sample-datasets/refs/heads/main/weather.csv"
|> downloadFileWithProgress "./downloaded_weather_test.csv"
|> startCustom template
|> Async.AwaitTask
|> Async.RunSynchronously
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment