All pastes #1266268 Raw Edit

Download Script v2

public text v1 · immutable
#1266268 ·published 2008-11-25 00:53 UTC
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 ] ]
  }
}