AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Concept: Multi Download in Background

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
fures



Joined: 31 Jan 2008
Posts: 30

PostPosted: Mon Jul 14, 2008 2:29 pm    Post subject: Concept: Multi Download in Background Reply with quote

I've made this proof of concept to make a more controllable URLDownloadToFile variant.

- This script creates a download queue
- Launches downloads as separate processes
- Monitors status of downloads

All that runs in the background, so your script can run undisturbed.

Hope it will be useful.

Code:

#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%
#Persistent

Dnl =
Max_Threads = 4

SetTimer,Check_myDnlList,1000
SetTimer,CheckReadyDNL,1000


Loop, 8
{
   thisurl = http://news.google.com
   FileSaveName = %A_ScriptDir%\Google.html
   Dnl = %Dnl%¤%thisurl%|%FileSaveName% ;Download Queue
}

MsgBox, The downloads have been started, just wait.`n`nThe script could run forward...

Return




Check_myDnlList:
Critical
   Loop, parse, Dnl, ¤
   {
      IfEqual,A_LoopField,
         Continue
      StringSplit,tDnl,A_LoopField,|
      turl = %tDnl1%
      tfil = %tDnl2%
      delthis =
      Loop, %Max_Threads% ;Check for empty runIDs
      {
         runIDx = runID%A_Index%
         IniRead, runID, %A_ScriptDir%\myDownload.ini, Running, %runIDx%, %A_Space%
         If !runID
         {
               ;scriptname "url" "save file" "pos-index" "dupl-filter"
            IfExist,C:\Program Files\AutoHotkey\AutoHotkey.exe
               Run, "C:\Program Files\AutoHotkey\AutoHotkey.exe" "myDownload.ahk" "%turl%" "%tfil%" %A_Index%,,,runID
            else IfExist,myDownload.exe
               Run, "myDownload.exe" "%turl%" "%tfil%" %A_Index%,,,runID
            else
            {
               MsgBox, The myDownload.exe component is missing, and AutoHotkey is not found.
               ExitApp
            }
            IniWrite, %runID%|%turl%|%tfil%, %A_ScriptDir%\myDownload.ini, Running, %runIDx%
            delthis = 1
            Break
         }
      }
      If delthis
      {
         ;here a regexreplace would be better...
         StringReplace, Dnl, Dnl, %A_LoopField%,, A
         StringReplace, Dnl, Dnl, ¤¤,¤, A
      }
   }
Return


CheckReadyDNL:
Critical
   Loop, %Max_Threads% ;Check for finished runID
   {
      runIDx = runID%A_Index%
      IniRead, runID, %A_ScriptDir%\myDownload.ini, Running, %runIDx%, %A_Space%
      If runID
      {
         StringSplit,tDnl,runID,|
         trunID = %tDnl1%
         turl = %tDnl2%
         tfil = %tDnl3%
         Process, Exist, %trunID%
         If not ErrorLevel ;This is ready
         {
            IniWrite, %A_Space%, %A_ScriptDir%\myDownload.ini, Running, %runIDx%
         }
      }
   }
Return




The download script (copy into the same folder)
Code:

#SingleInstance OFF
#NoTrayIcon
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

if 0 < 2  ; The left side of a non-expression if-statement is always the name of a variable.
{
    ;MsgBox This script requires at least 2 incoming parameters but it only received %0%.
;    ExitApp
}
StringReplace, 1, 1, ",, All
StringReplace, 2, 2, ",, All
StringReplace, 3, 3, ",, All
;StringReplace, 4, 4, ",, All

url = %1%
save = %2%
pospar = %3%
if not url
{
   url = http://www.bbdo.hu/mytest/magyar/works/007_work1.wmv
   sleep, 5000
}
if not save
   save = temp.wmv
if not pospar
   pospar = 1

   
   
SplitPath,save,file
rfile := SubStr(file,InStr(file,"_")+1)
;StringSplit,rfile,file,_
urlfile := file
If rfile
   urlfile := rfile

;message = 0x11100
;OnMessage(message, "SetCounter")


Loop, 20
{
   pos%A_Index% := ((A_Index-1) * 31)+100
}
posy := pos%pospar%

;Progress, x10 y%posy% M2 T FM8 FS8 h80 w300, , ., mydnl

;wn := WinExist("mydnl")
;WinMinimize,ahk_id %wn%

Gui, +lastfound -caption +Border +ToolWindow ;+owner
wn := WinExist()
Gui, Add, Progress, Section x55 vProgressBar w100 +Smooth cBDDCEF
Gui, Font, bold
Gui, Add, Text, ys, %urlfile%
Gui, Add, Text, vProgressN BackgroundTrans x90 ys+2, connecting...
Gui, Font
Gui, Add, Text, vKB ys w150, getting info...
Gui, Add, Button, ys x5 w48 h20 gExit, Close
Gui, Show, NoActivate x10 y%posy% w300 h30, Downloading...


total := HttpQueryInfo(url, 5)
If not total
   ExitApp

GuiControl, , KB, % "(" round(total/1024) " kB)"



FileDelete, %save%
res:=Download(url, save, message, 500)
ExitApp
Return

Exit:
GuiEscape:
GuiClose:
ExitApp

Download(url, save, msg = 0x1100, sleep = 1000) {
   ;total := HttpQueryInfo(url, 5)
   Global total
   SetTimer, _dlprocess, %sleep%
   UrlDownloadToFile, %url%, %save%
   SetTimer, _dlprocess, Off
   Return, ErrorLevel
   _dlprocess:
   FileGetSize, current, %save%, K
   ;Process, Exist
   ;PostMessage, msg, current * 1024, total, , ahk_pid %ErrorLevel%
   SetCounter(current * 1024, total)
   Exit
}
; SetCounter(wParam, lParam) {
   ; global url,save
   ; SplitPath,url,urlfile
   ; progress := Round(wParam / lParam * 100)
   ; wParam := wParam // 1024
   ; lParam := lParam // 1024
   ; Progress, %progress%, %url%, %urlfile%: %wParam% kB of %lParam% kB, %progress%`% - Downloading...
; }
SetCounter(wParam, lParam) {
   progress := Round(wParam / lParam * 100)
   GuiControl, , ProgressBar, %progress%
   GuiControl, , ProgressN, %progress%`%
   ;wParam := wParam // 1024
   ;lParam := lParam // 1024
   ;GuiControl, , KB, (%wParam% kB of %lParam% kB)
   ;Gui, Show, , %progress%`% - Downloading...
}


/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; HttpQueryInfo ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
QueryInfoFlag

HTTP_QUERY_RAW_HEADERS = 21
Receives all the headers returned by the server.
Each header is terminated by "\0". An additional "\0" terminates the list of headers.

HTTP_QUERY_CONTENT_LENGTH = 5
Retrieves the size of the resource, in bytes.

HTTP_QUERY_CONTENT_TYPE = 1
Receives the content type of the resource (such as text/html).

Find more at: http://msdn.microsoft.com/library/en-us/wininet/wininet/query_info_flags.asp

Proxy Settings:

INTERNET_OPEN_TYPE_PRECONFIG                    0   // use registry configuration
INTERNET_OPEN_TYPE_DIRECT                       1   // direct to net
INTERNET_OPEN_TYPE_PROXY                        3   // via named proxy
INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY  4   // prevent using java/script/INS

*/ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

HttpQueryInfo(URL, QueryInfoFlag=21, Proxy="", ProxyBypass="") {
   hModule := DllCall("LoadLibrary", "str", "wininet.dll")

   If (Proxy != "")
      AccessType=3
   Else
      AccessType=1

   io_hInternet := DllCall("wininet\InternetOpenA"
   , "str", "" ;lpszAgent
   , "uint", AccessType
   , "str", Proxy
   , "str", ProxyBypass
   , "uint", 0) ;dwFlags
   If (ErrorLevel != 0 or io_hInternet = 0) {
   DllCall("FreeLibrary", "uint", hModule)
   return, -1
   }

   iou_hInternet := DllCall("wininet\InternetOpenUrlA"
   , "uint", io_hInternet
   , "str", url
   , "str", "" ;lpszHeaders
   , "uint", 0 ;dwHeadersLength
   , "uint", 0x80000000 ;dwFlags: INTERNET_FLAG_RELOAD = 0x80000000 // retrieve the original item
   , "uint", 0) ;dwContext
   If (ErrorLevel != 0 or iou_hInternet = 0) {
   DllCall("FreeLibrary", "uint", hModule)
   return, -1
   }

   VarSetCapacity(buffer, 1024, 0)
   VarSetCapacity(buffer_len, 4, 0)

   Loop, 5
   {
     hqi := DllCall("wininet\HttpQueryInfoA"
     , "uint", iou_hInternet
     , "uint", QueryInfoFlag ;dwInfoLevel
     , "uint", &buffer
     , "uint", &buffer_len
     , "uint", 0) ;lpdwIndex
     If (hqi = 1) {
       hqi=success
       break
     }
   }

   IfNotEqual, hqi, success, SetEnv, res, timeout

   If (hqi = "success") {
   p := &buffer
   Loop
   {
     l := DllCall("lstrlen", "UInt", p)
     VarSetCapacity(tmp_var, l+1, 0)
     DllCall("lstrcpy", "Str", tmp_var, "UInt", p)
     p += l + 1
     res := res  . "`n" . tmp_var
     If (*p = 0)
     Break
   }
   StringTrimLeft, res, res, 1
   }

   DllCall("wininet\InternetCloseHandle",  "uint", iou_hInternet)
   DllCall("wininet\InternetCloseHandle",  "uint", io_hInternet)
   DllCall("FreeLibrary", "uint", hModule)

   return, res
}






PS: I used some code from other coders in my script:
- HTTPQueryInfo from olfen
Thanks.



Cheers,

fures
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group