rendered paste body
;Usage: $download(<file URL>,[Save Directory],[Save File Name])
;Will return download ID number if successful, error message otherwise
;$dlinfo(<download ID>)[.prop]
;Returns information about a current download
;Properties: size, file, url, rate, down, status, percent
;$downloads(<N>)
;If N = 0, returns number of current downloads
;Returns download ID of Nth download
;To be added/fixed/changed:
;Add flags for remove file if exists, append to file (prop?)
;Completion command
;Run on completion
;More Status prop information (Connecting, Completed, Initiated)
;Variables not being deleted properly at the end of the download.
;Stopping downloads
on *:START: {
unset %file_dl.*
}
alias download {
var %time = $ticks $+ $rand(1,1000)
;Settings Variables
var %directory = $mircdirdownload
var %redirect_limit = 3
;End Settings Variables
;Determine download directory
if ((!$isid) && (!$sock($1))) { var %error = Please use in identifier format: $chr(36) $+ download(<download URL>,[save directory],[save filename]) | goto error }
if ($isid) {
if ($2) %directory = $v1
if (!$isdir($nofile(%directory))) { var %error = Download directory does not exist. | goto error }
}
else {
%time = $gettok($1,-1,46)
download_close $1
}
;Determine download target properties
var %url_regex = /(?:\s|\G)((?:(?:http(s?):\/\/|www\.())(?:[\w-]*\.)*?(?:[\w-]*)(?:\.[a-z]{2,5}(?:\.[a-z]{2})?))|(?:http(s?):\/\/(?:\d{1,3}\.){3}\d{1,3}))((?::\d{1,5}?)?)((?:\/\S*)*)(?:\s|$)/i
var %match = $regex($strip($iif($isid,$1,$2-)),%url_regex))
if (!%match) { var %error = Valid URL required for download. | goto error }
;;Determine download port
var %secure = $false
if ($regml(2)) {
var %port = 443
%secure = $true
}
else var %port = 80
if ($regml(3)) %port = $right($v1,-1)
;;Determine download host
var %host = $remove($regml(1),http://,https://)
;Set socket information variables
set %file_dl.path. [ $+ [ %time ] ] $iif($regml(4),$v1,/)
set %file_dl.head. [ $+ [ %time ] ] 1
;Set filename/path
if ($isid) {
if ($3) set %file_dl.save. [ $+ [ %time ] ] $v1
elseif ($regex($gettok($gettok(%file_dl.path. [ $+ [ %time ] ],-1,47\),-1,92),/([^?&#:*"<>]+)/)) set %file_dl.save. [ $+ [ %time ] ] $regml(1)
else set %file_dl.save. [ $+ [ %time ] ] index.html
%file_dl.save. [ $+ [ %time ] ] = $+(%directory,$iif($right(%directory,1) !isin \/,\),%file_dl.save. [ $+ [ %time ] ])
if $exists(%file_dl.save. [ $+ [ %time ] ]) { var %error = File already exists. | goto error }
}
;Handle Redirects. Filename previously set on first connection
else {
inc %file_dl.redirect. [ $+ [ %time ] ]
if (%file_dl.redirect. [ $+ [ %time ] ] > %redirect_limit) { var %error = Redirection limit exceeded. | goto error }
unset %file_dl.keep. [ $+ [ %time ] ]
}
sockopen $iif(%secure,-e) download. $+ %time %host %port
;Done
return %time
:error
$iif($isid,return,echo 4 -a) Error: $iif(%error,$v1,$error)
reseterror
unset %file_dl.*. [ $+ [ %time ] ]
}
on *:SOCKOPEN:download.*: {
if ($sockerr) { download_close $sockname | return }
sockwrite -nt $sockname GET %file_dl.path. [ $+ [ $gettok($sockname,-1,46) ] ] HTTP/1.1
sockwrite -nt $sockname Host: $sock($sockname).addr
sockwrite -nt $sockname Accept-Language: en-us
sockwrite -nt $sockname User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6
sockwrite -nt $sockname Accept: */*
sockwrite -nt $sockname Connection: close
sockwrite -nt $sockname
}
on *:SOCKREAD:download.*: {
if ($sockerr > 0) return
var %download_read
var %time = $gettok($sockname,-1,46)
:download_read
;Process Headers First
if (%file_dl.head. [ $+ [ %time ] ]) {
sockread %download_read
if (!%download_read) {
unset %file_dl.head. [ $+ [ %time ] ]
goto download_read
}
if ($regex(redirect,%download_read,/Location:\s(.*?)$/i)) {
var %new_page = $iif(!$regex($left($regml(redirect,1),8),/^http(s)?:\/\//i),$+(http,$iif($sock($sockname).ssl,s),://,$sock($sockname).addr,:,$sock($sockname).port,$iif($left($regml(redirect,1),1) != /,/),$regml(redirect,1)),$regml(redirect,1))
set %file_dl.keep. [ $+ [ %time ] ] $true
download $sockname %new_page
return
}
if ($regex(size,%download_read,/Content-Length:\s(.*?)$/i)) {
set %file_dl.size. [ $+ [ %time ] ] $regml(size,1)
goto download_read
}
goto download_read
}
;Headers are done, process file download
sockread -f &download_read
inc %file_dl.bytes. [ $+ [ %time ] ] $sockbr
bwrite $qt(%file_dl.save. [ $+ [ %time ] ]) -1 $sockbr &download_read
if ($calc($ticks - %file_dl.lastrate. [ $+ [ %time ] ] ) > 500) {
if (%file_dl.lastrate. [ $+ [ %time ] ] ) set %file_dl.rate. [ $+ [ %time ] ] $calc((%file_dl.bytes. [ $+ [ %time ] ] - %file_dl.ratesize. [ $+ [ %time ] ] ) / ($ticks - $v1) * 1000)
set %file_dl.lastrate. [ $+ [ %time ] ] $ticks
set %file_dl.ratesize. [ $+ [ %time ] ] %file_dl.bytes. [ $+ [ %time ] ]
}
if ($sockbr == 0) return
goto download_read
:error
echo 4 -a Error: $error
reseterror
download_close $sockname
return
}
alias dlinfo {
if (!$isid) { var %error = Please use in identifier format. | goto error }
if ($1 !isnum) { var %error = Invalid parameters. | goto error }
if (($prop == status) || (!$prop)) return $iif(%file_dl.save. [ $+ [ $1 ] ],Active)
if ($prop == size) return %file_dl.size. [ $+ [ $1 ] ]
if ($prop == file) return %file_dl.save. [ $+ [ $1 ] ]
if ($prop == url) return %file_dl.save. [ $+ [ $1 ] ]
if ($prop == rate) return %file_dl.rate. [ $+ [ $1 ] ]
if ($prop == down) return %file_dl.bytes. [ $+ [ $1 ] ]
if ($prop == percent) return $calc(%file_dl.bytes. [ $+ [ $1 ] ] / %file_dl.size. [ $+ [ $1 ] ] *100)
return
:error
$iif($isid,return,echo 4 -a) Error: $iif($error,$v1,%error)
reseterror
}
alias downloads {
if (!$isid) return
if ($1 == 0) return $var(%file_dl.save.*,0)
return $gettok($var(%file_dl.save.*,$1),-1,46)
}
on *:SOCKCLOSE:download.*: {
echo -a Download complete: $qt(%file_dl.save. [ $+ [ $gettok($sockname,-1,46) ] ])
download_close $sockname
}
alias -l download_close {
var %time = $gettok($1,-1,46)
if ($sock(download. $+ %time)) sockclose download. $+ %time
if (!%file_dl.keep. [ $+ [ %time ] ] ) {
unset %file_dl.*. [ $+ [ %time ] ]
}
}