Skip to content

add download.bat #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
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
185 changes: 185 additions & 0 deletions hybrids/.net/powershell/download.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
<# :
@setlocal disabledelayedexpansion enableextensions
@echo off
powershell -nol -noni -nop -ex bypass -c "&{[ScriptBlock]::Create((cat '%~f0') -join [Char[]]10).Invoke(@(&{$args}%*))}"
exit /b
#>

function filesize($length) {
if($length -gt 1073741824) {
"{0:n1} GB" -f ($length / 1073741824)
} elseif($length -gt 1048576) {
"{0:n1} MB" -f ($length / 1048576)
} elseif($length -gt 1024) {
"{0:n1} KB" -f ($length / 1024)
} else {
"$($length) B"
}
}

function ftp_file_size($url) {
$request = [net.ftpwebrequest]::create($url)
$request.method = [net.webrequestmethods+ftp]::getfilesize
$request.getresponse().contentlength
}

function url_remote_filename($url) {
$uri = (new-object URI $url)
$basename = split-path $uri.PathAndQuery -leaf
if($basename -match ".*[?=]+([\w._-]+)") {
$basename = $matches[1]
}
if(($basename -notlike "*.*") -or ($basename -match "^[v.\d]+$")) {
$basename = split-path $uri.AbsolutePath -leaf
}
if(($basename -notlike "*.*") -and ($uri.Fragment -ne "")) {
$basename = $uri.Fragment.Trim('/', '#')
}
return $basename
}

function dl($url, $to, $progress) {
[System.Net.ServicePointManager]::SecurityProtocol = 4032
$reqUrl = ($url -split "#")[0]
$wreq = [net.webrequest]::create($reqUrl)

try {
$wres = $wreq.GetResponse()
} catch [System.Net.WebException] {
$exc = $_.Exception
$handledCodes = @(
[System.Net.HttpStatusCode]::MovedPermanently, # HTTP 301
[System.Net.HttpStatusCode]::Found, # HTTP 302
[System.Net.HttpStatusCode]::SeeOther, # HTTP 303
[System.Net.HttpStatusCode]::TemporaryRedirect # HTTP 307
)

$redirectRes = $exc.Response
if ($handledCodes -notcontains $redirectRes.StatusCode) {
throw $exc
}

if ((-not $redirectRes.Headers) -or ($redirectRes.Headers -notcontains 'Location')) {
throw $exc
}

$newUrl = $redirectRes.Headers['Location']

if ($url -like '*#/*') {
$null, $postfix = $url -split '#/'
$newUrl = "$newUrl#/$postfix"
}
dl $newUrl $to $progress
return
}

if(-not $to) {
$to = url_remote_filename $url
}

$total = $wres.ContentLength
if($total -eq -1 -and $wreq -is [net.ftpwebrequest]) {
$total = ftp_file_size($url)
}

if ($progress -and ($total -gt 0)) {
[console]::CursorVisible = $false
function dl_onProgress($read) {
dl_progress $read $total $(split-path $to -leaf)
}
} else {
if($total -gt 0) {
write-host "Downloading $url ($(filesize $total))..."
} else {
write-host "Downloading $url ..."
}
function dl_onProgress {
#no op
}
}

try {
$s = $wres.getresponsestream()
$fs = [io.file]::openwrite($to)
$buffer = new-object byte[] 2048
$totalRead = 0
$sw = [diagnostics.stopwatch]::StartNew()

dl_onProgress $totalRead
while(($read = $s.read($buffer, 0, $buffer.length)) -gt 0) {
$fs.write($buffer, 0, $read)
$totalRead += $read
if ($sw.elapsedmilliseconds -gt 100) {
$sw.restart()
dl_onProgress $totalRead
}
}
$sw.stop()
dl_onProgress $totalRead
} finally {
if ($progress) {
[console]::CursorVisible = $true
write-host
}
if ($fs) {
$fs.close()
}
if ($s) {
$s.close();
}
$wres.close()
}
}

function dl_progress_output($filename, $read, $total, $console) {
$p = [math]::Round($read / $total * 100, 0)

$left = "$filename ($(filesize $total))"
$right = [string]::Format("{0,3}%", $p)
$midwidth = $console.BufferSize.Width - ($left.Length + $right.Length + 8)
$completed = [math]::Abs([math]::Round(($p / 100) * $midwidth, 0) - 1)

if ($completed -gt 1) {
$dashes = [string]::Join("", ((1..$completed) | ForEach-Object {"="}))
}

$dashes += switch($p) {
100 {"="}
default {">"}
}

$spaces = switch($dashes.Length) {
$midwidth {[string]::Empty}
default {
[string]::Join("", ((1..($midwidth - $dashes.Length)) | ForEach-Object {" "}))
}
}

"$left [$dashes$spaces] $right"
}

function dl_progress($read, $total, $filename) {
$console = $host.UI.RawUI;
$left = $console.CursorPosition.X;
$top = $console.CursorPosition.Y;
$width = $console.BufferSize.Width;

if($read -eq 0) {
$maxOutputLength = $(dl_progress_output $filename 100 $total $console).length
if (($left + $maxOutputLength) -gt $width) {
write-host
$left = 0
$top = $top + 1
if($top -gt $console.CursorPosition.Y) { $top = $console.CursorPosition.Y }
}
}

write-host $(dl_progress_output $filename $read $total $console) -nonewline
[console]::SetCursorPosition($left, $top)
}

if ($args.count -gt 0) {
dl $args[0] $args[1] $(!([console]::isoutputredirected))
} else {
write-host "Usage: download <url> [outfile]"
}