[bb] BlitzLeech by BlitzSupport [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:42

Previous topic - Next topic

BlitzBot

Title : BlitzLeech
Author : BlitzSupport
Posted : 1+ years ago

Description : UPDATE: Fixed stupid case-sensitivity bug!

This is a rough attempt at a file downloader, sorta like GoZilla or something, except a) it doesn't resume yet (doh!) and b) it needs Blitz to support threads before it'll be properly useable/fast...

Note that it'll download into 'path$' (default: "C:"), and it's not particularly reliable yet! Read the disclaimer in the code :)


Code :
Code (blitzbasic) Select
; -----------------------------------------------------------------------------
; BlitzLeech -- simple HTTP 1.1 downloader... james @ hi - toro . com
; -----------------------------------------------------------------------------

; Instructions/disclaimers/excuses...

; Paste URLs into top text field. Click Leech. Slow due to unthreaded-ness and
; some hackiness to try and work around it a little... delays expected on
; connection and disconnection from server, hence apparent freeze-ups! List-view
; NOT properly updated, so don't worry. Abort or Exit will clean everything up,
; though the downloaded files will remain...

; -----------------------------------------------------------------------------
; Hacky work-in-progress! Judge not beta code lest ye beta code be judged, etc.
; -----------------------------------------------------------------------------



; CHANGE TO SUIT...

Global path$ = "C:" ; Temp download folder -- careful, in case you have other
; files here with the same name as a download!





; -----------------------------------------------------------------------------
; Name of download program...
; -----------------------------------------------------------------------------

Global Leecher$ = "BlitzLeech Plus"

Global list

; -----------------------------------------------------------------------------
; Download type... [NOT ALL RELEVANT. TO BE SORTED!]
; -----------------------------------------------------------------------------

Type Download

Field folder$
Field filename$
Field savestream

Field listpos

Field webstream

Field url$
Field host$
Field file$
Field header$
Field totalbytes
Field currentbyte
Field date$
Field server$
Field content$
Field reply$

End Type

; -----------------------------------------------------------------------------
; StartDownload -- starts downloading a file...
; -----------------------------------------------------------------------------

; NOTE: This part causes a delay. This is because it has to connect to the
; server and then wait for it to reply. This could only really be avoided
; by creating a new thread for each download, which ain't gonna happen soon!

Function StartDownload.Download (url$, folder$, filename$ = "")

; -------------------------------------------------------------------------
; Create new download...
; -------------------------------------------------------------------------

d.Download = New Download

dlistpos = -1

; -------------------------------------------------------------------------
; Remove "http://" from URL if it's there...
; -------------------------------------------------------------------------

If Left (url$, 7) = "http://" Then url$ = Right (url$, Len (url$) - 7)
durl = url$

; -------------------------------------------------------------------------
; Split into host ("www.whatever.com") and remote filename ("/text/test.txt")...
; -------------------------------------------------------------------------

slash = Instr (url$, "/")
If slash
dhost = Left (url$, slash - 1)
dfile = Right (url$, Len (url$) - slash + 1)
Else
dhost$ = url$
dfile$ = "/"
EndIf

; -------------------------------------------------------------------------
; Local folder (add trailing slash if missing)...
; -------------------------------------------------------------------------

If Right (folder$, 1) <> "" Then folder$ = folder$ + ""
dfolder$ = folder$

; -------------------------------------------------------------------------
; Filename...
; -------------------------------------------------------------------------

If filename$ = ""
If dfile = "/"
filename$ = "Unknown file.txt"
Else
For findSlash = Len (dfile$) To 1 Step - 1
testForSlash$ = Mid (dfile$, findSlash, 1)
If testForSlash$ = "/"
filename$ = Right (dfile$, Len (dfile$) - findSlash)
Exit
EndIf
Next
If filename$ = "" Then filename$ = "Unknown file.txt"
EndIf
EndIf

dfilename$ = filename$

; -------------------------------------------------------------------------
; Open connection to server...
; -------------------------------------------------------------------------

dwebstream = OpenTCPStream (dhost, 80)

If dwebstream

; ---------------------------------------------------------------------
; Send request header...
; ---------------------------------------------------------------------

WriteLine dwebstream, "GET " + dfile + " HTTP/1.1"
WriteLine dwebstream, "Host: " + dhost
WriteLine dwebstream, "User-Agent: "+ Leecher$
WriteLine dwebstream, "Accept: */*"
WriteLine dwebstream, ""

; ---------------------------------------------------------------------
; Server replies with several lines followed by a blank line...
; ---------------------------------------------------------------------

Repeat

; -----------------------------------------------------------------
; Read one line of server's response header...
; -----------------------------------------------------------------

dheader = ReadLine (dwebstream)

deply = "" ; Reset reply string...

; -----------------------------------------------------------------
; Replies are in the form of "Blah: xxxx" (note colon and space)...
; -----------------------------------------------------------------

pos = Instr (dheader, ": ")
If pos
deply = Left (dheader, pos + 1)
EndIf

; -----------------------------------------------------------------
; ReplyContent () gets the actual information for each line...
; -----------------------------------------------------------------

Select Lower (deply)
Case "content-length: "
d otalbytes = ReplyContent (d)
Case "date: "
ddate = ReplyContent (d)
Case "server: "
dserver = ReplyContent (d)
Case "content-type: "
dcontent = ReplyContent (d)
Default
If gotReply = 0 Then initialReply$ = dheader: gotReply = 1
End Select

Until dheader = "" Or (Eof (dwebstream))

; ---------------------------------------------------------------------
; Fie size is zero? Weird. Oh, well, end of download...
; ---------------------------------------------------------------------

If d otalbytes = 0
CloseTCPStream dwebstream
Delete d
Return Null
EndIf

; ---------------------------------------------------------------------
; Create new file to write downloaded bytes into...
; ---------------------------------------------------------------------

dsavestream = WriteFile (dfolder + dfilename)

; ---------------------------------------------------------------------
; Couldn't create file? Too bad. End of download...
; ---------------------------------------------------------------------

If Not dsavestream
CloseTCPStream dwebstream
Delete d
Return Null
EndIf

; ---------------------------------------------------------------------
; Got all the information we need to continue the download...
; ---------------------------------------------------------------------

Return d

Else

; ---------------------------------------------------------------------
; Failed to connect to server...
; ---------------------------------------------------------------------

Delete d
Return Null

EndIf

End Function

; -----------------------------------------------------------------------------
; UpdateDownloads -- updates downloads and returns number of active downloads...
; -----------------------------------------------------------------------------

Function UpdateDownloads ()

; -------------------------------------------------------------------------
; Go through each .Download...
; -------------------------------------------------------------------------

For d.Download = Each Download

; ---------------------------------------------------------------------
; Count downloads still ongoing...
; ---------------------------------------------------------------------

downloads = downloads + 1

If Not Eof (dwebstream)

; -----------------------------------------------------------------
; Still receiving from server, so write bytes to local file...
; -----------------------------------------------------------------

For a = 1 To 10
If Not Eof (dwebstream)
WriteByte dsavestream, ReadByte (dwebstream)
dcurrentbyte = dcurrentbyte + 1
ModifyGadgetItem list, dlistpos, durl + " (" + dcurrentbyte + " / " + d otalbytes + " bytes)"
Else
Exit
EndIf
Next

Else

; -----------------------------------------------------------------
; Server's all done. End of download... [ADD FILE SIZE CHECK!]
; -----------------------------------------------------------------

RemoveGadgetItem list, dlistpos
ClearGadgetItems list
For d2.Download = Each Download
If d2 <> d
AddGadgetItem list, d2url + " (" + d2currentbyte + " / " + d2 otalbytes + " bytes)", True
d2listpos = SelectedGadgetItem (list)
EndIf
Next

CloseFile dsavestream
CloseTCPStream dwebstream
; Notify durl + " complete!"
Delete d

downloads = downloads - 1

EndIf

Next

; -------------------------------------------------------------------------
; Return number of downloads still ongoing...
; -------------------------------------------------------------------------

Return downloads

End Function

; -----------------------------------------------------------------------------
; ReplyContent -- just strips left-side of server reply ("Blah: " part)...
; -----------------------------------------------------------------------------

Function ReplyContent$ (d.Download)
Return Right (dheader, Len (dheader) - Len (deply))
End Function

; -----------------------------------------------------------------------------
; Percent -- returns percentage of 'current byte' / 'total bytes' ...
; -----------------------------------------------------------------------------

Function Percent# (part#, total#)
Return part / total
End Function

; -----------------------------------------------------------------------------
; AbortDownloads -- safely abort all downloads (eg. on quitting early)...
; -----------------------------------------------------------------------------

Function AbortDownloads ()
For d.Download = Each Download
CloseFile dsavestream
CloseTCPStream dwebstream
Delete d
ClearGadgetItems list
Next
End Function

; -----------------------------------------------------------------------------
; D E M O . . .
; -----------------------------------------------------------------------------

Function CenterWindow (title$, width, height, group = 0, style = 15)
Return CreateWindow (title$, (ClientWidth (Desktop ()) / 2) - (width / 2), (ClientHeight (Desktop ()) / 2) - (height / 2), width, height, group, style)
End Function

Const EVENT_None = $0 ; No event (eg. a WaitEvent timeout)
Const EVENT_KeyDown = $101 ; Key pressed
Const EVENT_KeyUp = $102 ; Key released
Const EVENT_ASCII = $103 ; ASCII key pressed
Const EVENT_MouseDown = $201 ; Mouse button pressed
Const EVENT_MouseUp = $202 ; Mouse button released
Const EVENT_MouseMove = $203 ; Mouse moved
Const EVENT_Gadget = $401 ; Gadget clicked
Const EVENT_Move = $801 ; Window moved
Const EVENT_Size = $802 ; Window resized
Const EVENT_Close = $803 ; Window closed
Const EVENT_Front = $804 ; Window brought to front
Const EVENT_Menu = $1001 ; Menu item selected
Const EVENT_LostFocus = $2001 ; App lost focus
Const EVENT_GotFocus = $2002 ; App got focus
Const EVENT_Timer = $4001 ; Timer event occurred

AppTitle Leecher$

window = CenterWindow (Leecher$, 400, 300, 0, 1 + 2)
SetMinWindowSize window, 340, 200

url = CreateTextField (5, 5, ClientWidth (window) - 80, 25, window)
go = CreateButton ("Leech!", ClientWidth (window) - 70, 5, 65, 25, window)
list = CreateListBox (5, 35, ClientWidth (window) - 10, ClientHeight (window) - 110, window)
prog = CreateProgBar (5, ClientHeight (window) - 65, ClientWidth (window) - 10, 25, window)
abort = CreateButton ("Abort all downloads", 5, ClientHeight (window) - 30, 150, 25, window)
quit = CreateButton ("Exit program", ClientWidth (window) - 160, ClientHeight (window) - 30, 150, 25, window)

SetGadgetLayout url, 1, 1, 1, 0
SetGadgetLayout go, 0, 1, 1, 0
SetGadgetLayout list, 1, 1, 1, 1
SetGadgetLayout prog, 1, 1, 0, 1
SetGadgetLayout abort, 1, 0, 0, 1
SetGadgetLayout quit, 0, 1, 0, 1

ActivateGadget url

Repeat

e = WaitEvent (10)

Select e
Case EVENT_Gadget

Select EventSource ()

Case url
If EventData () = 13
leech$ = TextFieldText (url)
If leech$ <> ""
DisableGadget url
DisableGadget go
dl.Download = StartDownload (leech$, path$, "")
If dl = Null
Notify "Download of " + Chr (34) + leech$ + Chr (34) + " failed!"
Else
count = count + 1
AddGadgetItem list, dlurl + " (" + dlcurrentbyte + " / " + dl otalbytes + " bytes)", True
dllistpos = SelectedGadgetItem (list)
EndIf
SetGadgetText url, ""
EnableGadget url
EnableGadget go
ActivateGadget url
EndIf
EndIf
Case go
leech$ = TextFieldText (url)
If leech$ <> ""
DisableGadget url
DisableGadget go
dl.Download = StartDownload (leech$, path$, "")
If dl = Null
Notify "Download of " + Chr (34) + leech$ + Chr (34) + " failed!"
Else
count = count + 1
AddGadgetItem list, dlurl + " (" + dlcurrentbyte + " / " + dl otalbytes + " bytes)", True
dllistpos = SelectedGadgetItem (list)
EndIf
SetGadgetText url, ""
EnableGadget url
EnableGadget go
ActivateGadget url
EndIf
Case abort
AbortDownloads ()
UpdateProgBar prog, 0
Case quit
AbortDownloads ()
UpdateProgBar prog, 0
End
Case list
pos = SelectedGadgetItem (list)
For dl.Download = Each Download
If dllistpos = pos
message$ = "Folder: " + dlfolder
message$ = message$ + Chr (10) + "Filename: " + dlfilename
message$ = message$ + Chr (10) + "List position: " + dllistpos + " (check = " + pos + ")"
message$ = message$ + Chr (10) + "URL: " + dlurl
message$ = message$ + Chr (10) + "Host: " + dlhost
message$ = message$ + Chr (10) + "File: " + dlfile
message$ = message$ + Chr (10) + "Header: " + dlheader
message$ = message$ + Chr (10) + "Total bytes: " + dl otalbytes
message$ = message$ + Chr (10) + "Current byte: " + dlcurrentbyte
message$ = message$ + Chr (10) + "Date: " + dldate
message$ = message$ + Chr (10) + "Server: " + dlserver
message$ = message$ + Chr (10) + "Content: " + dlcontent
message$ = message$ + Chr (10) + "Reply: " + dleply
Notify message$
Exit
EndIf
Next

End Select

End Select

UpdateDownloads ()

pos = SelectedGadgetItem (list)
For dl.Download = Each Download
If dllistpos = pos
UpdateProgBar prog, Percent (dlcurrentbyte, dl otalbytes)
EndIf
Next

Until e = EVENT_Close

End


Comments : none...