Posted: Sun Aug 19, 2007 6:58 pm
It's a big update
(~ 500 lines )
- Youtube : OK
- DailyMotion : OK
- GoogleVideo : ERROR
http://files-upload.com/files/444567/PureTube.zip
XML examples

- Youtube : OK
- DailyMotion : OK
- GoogleVideo : ERROR
http://files-upload.com/files/444567/PureTube.zip
Code: Select all
;/ PureBasic 4.10b2
; Version 2.0
; Added : ProgressBar + Cancel Download + Size Downloaded / File Size / rate
; Added : Cancel Button / Resize / Translation in English
#Title="PureTube - Download "
#TitleNext=" at "
Global VideoTitle.s, VideoId.s, Path.s
Global DownloadURL.s, DownloadFilename.s, StopDownload, IsDownloading
Global SourceName.s, SourceURL.s
Global IdBegin.s,IdEnd.s
Global TitleBegin.s,TitleEnd.s
Global UrlInit.s, UrlBegin.s, UrlEnd.s, UrlDecodeMode.s
Enumeration
#Web
#ToolBar
#Home
#Back
#Forward
#Download
#Cancel
#StatusBar
#Progress
#Folder
#FolderSetup
#FolderOpen
#Sources
#SourceAdd
#FolderMenu
#SourceMenu
EndEnumeration
DataSection
Back:IncludeBinary "back.ico"
Forward:IncludeBinary "forward.ico"
Home:IncludeBinary "home.ico"
Save:IncludeBinary "Download.ico"
Stop:IncludeBinary "Cancel.ico"
Chemin:IncludeBinary "Path.ico"
Options:IncludeBinary "Options.ico"
EndDataSection
;{ Generic Functions
; For Decoding URL
Procedure HexVal(a$)
a$=Trim(UCase(a$))
If Asc(a$)='$'
a$=Trim(Mid(a$,2,Len(a$)-1))
EndIf
Protected Result=0
Protected *adr.Byte=@a$
For i=1 To Len(a$)
Result<<4
Select *adr\B
Case '0'
Case '1':Result+1
Case '2':Result+2
Case '3':Result+3
Case '4':Result+4
Case '5':Result+5
Case '6':Result+6
Case '7':Result+7
Case '8':Result+8
Case '9':Result+9
Case 'A':Result+10
Case 'B':Result+11
Case 'C':Result+12
Case 'D':Result+13
Case 'E':Result+14
Case 'F':Result+15
Default:i=Len(a$)
EndSelect
*adr+1
Next
ProcedureReturn Result
EndProcedure
; For Decoding URL
Procedure.s DecodeURL(In.s)
Protected i=FindString(In,"%",1)
While (i)
In = ReplaceString(In,Mid(In,i,3),Chr(HexVal(Mid(In,i+1,2))))
i=FindString(In,"%",1)
Wend
Protected Out.s =In
ProcedureReturn Out
EndProcedure
; For Form
Procedure ToolBarImageButtonEx(ToolBarId,ButtonId,ImageId,ToolTip.s)
ToolBarImageButton(ButtonId,ImageId)
ToolBarToolTip(ToolBarId,ButtonId,ToolTip)
EndProcedure
;}
;{ Video MultiSources
Procedure InitSourceParser(Xml.s)
; Read XML file
Protected XmlID = LoadXML(#PB_Any,Xml)
Protected XmlNode,XmlSubnode
; Get parser parameters from XML file
If (XmlID And XMLStatus(XmlID)=0)
XmlNode = XMLNodeFromID(XmlID,SourceName)
XmlSubnode = XMLNodeFromPath(XmlNode,"homepage")
If (XmlSubnode)
SourceURL = GetXMLAttribute(XmlSubnode,"url")
EndIf
XmlSubnode = XMLNodeFromPath(XmlNode,"download")
If (XmlSubnode)
UrlInit = GetXMLAttribute(XmlSubnode,"url")
UrlBegin = GetXMLAttribute(XmlSubnode,"begin")
UrlEnd = GetXMLAttribute(XmlSubnode,"end")
UrlDecodeMode = GetXMLAttribute(XmlSubnode,"decode")
EndIf
XmlSubnode = XMLNodeFromPath(XmlNode,"title")
If (XmlSubnode)
TitleBegin = GetXMLAttribute(XmlSubnode,"begin")
TitleEnd = GetXMLAttribute(XmlSubnode,"end")
EndIf
XmlSubnode = XMLNodeFromPath(XmlNode,"vid")
If (XmlSubnode)
IdBegin = GetXMLAttribute(XmlSubnode,"begin")
IdEnd = GetXMLAttribute(XmlSubnode,"end")
EndIf
;FreeXML(XmlID)
Else
MessageRequester("Warning!","Error reading XML!" ,#MB_ICONWARNING)
ProcedureReturn
EndIf
EndProcedure
Procedure InitSourceList(Xml.s)
; Get parser parameters from XML file
Protected XmlID = LoadXML(#PB_Any,Xml)
Protected XmlNode,XmlSubnode
Protected Result.s
; Create source list
If (XmlID And XMLStatus(XmlID)=0)
XmlNode = RootXMLNode(XmlID)
XmlNode = XMLNodeFromPath(XmlNode,"/sources/source[0]")
CreatePopupMenu(#SourceMenu)
MenuItemID=#SourceMenu
Repeat
MenuItemID+1
MenuItem(MenuItemID,GetXMLAttribute(XmlNode,"id"))
XmlNode=NextXMLNode(XmlNode)
Until (XmlNode=0)
MenuBar()
MenuItem(#SourceAdd,"New Source...")
DisableMenuItem(#SourceMenu,#SourceAdd,1)
;FreeXML(XmlID)
Else
MessageRequester("Warning!","Error reading XML!" ,#MB_ICONWARNING)
ProcedureReturn
EndIf
EndProcedure
;}
;{ Download Video
Procedure SaveVideoFile(VideoId.s)
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
; ***************************
; Windows OS code
; ***************************
;/ ( Downloader With progress And Status By Joakim L. Christiansen )
DisableToolBarButton(#ToolBar,#Cancel,#False)
IsDownloading+#True
Protected hInet, hURL, Bytes
Protected BufferLength = 2048, Buffer.s = Space(BufferLength)
Protected url.s = DownloadURL.s
Protected Filename.s = DownloadFilename.s
Protected File
Protected CurrentSize, PreviousSize, FileSize, time, BytesPerSecond
Protected Domain.s, String.s, i, BufferLengthWas = BufferLength
Protected hInetCon, hHttpOpenRequest, iretval
hInet = InternetOpen_("Downloader",0,0,0,0)
hURL = InternetOpenUrl_(hInet,url.s,0,0,$80000000,0)
;Get filesize
Domain.s = StringField(url.s,3,"/")
hInetCon = InternetConnect_(hInet,Domain.s,80,#Null,#Null,3,0,0)
If hInetCon
hHttpOpenRequest = HttpOpenRequest_(hInetCon,"HEAD",ReplaceString(url.s,"http://"+Domain.s+"/",""),#Null,#Null,0,$80000000,0)
If hHttpOpenRequest
iretval = HttpSendRequest_(hHttpOpenRequest,#Null,0,0,0)
If iretval
HttpQueryInfo_(hHttpOpenRequest,19,@Buffer.s,@BufferLength,0) ;changes the buffer length
String.s = PeekS(@Buffer.s,BufferLength): BufferLength = BufferLengthWas
If Trim(String.s) = "200"
HttpQueryInfo_(hHttpOpenRequest,22,@Buffer.s,@BufferLength,0)
String.s = PeekS(@Buffer.s,BufferLength): BufferLength = BufferLengthWas
If FindString(String.s,"Content-Length:",1)
i = FindString(String.s,"Content-Length:",1) + Len("Content-Length:")
String.s = Mid(String.s,i,Len(String.s)-i)
FileSize = Val(Trim(String.s))
EndIf
EndIf
EndIf
EndIf
EndIf
;Download file and update status
If hURL
File = CreateFile(#PB_Any,Filename.s)
If File
time = ElapsedMilliseconds()
SetGadgetAttribute(#Progress,#PB_ProgressBar_Maximum,FileSize)
While InternetReadFile_(hURL,@Buffer.s,BufferLength,@Bytes) And Bytes > 0
If StopDownload
Break
EndIf
WriteData(File,@Buffer.s,Bytes)
CurrentSize + Bytes
SetGadgetState(#Progress,CurrentSize)
StatusBarText(#StatusBar,0," "+Str(CurrentSize/1024)+"/"+Str(FileSize/1024)+"kb - "+Str(BytesPerSecond/1024)+"kb/s")
If time < ElapsedMilliseconds() - 1000
time = ElapsedMilliseconds()
BytesPerSecond = CurrentSize - PreviousSize
PreviousSize = CurrentSize
EndIf
Wend
CloseFile(File)
Else
MessageRequester("Warning!","Error creating file!",#MB_ICONWARNING)
EndIf
StopDownload = #False
IsDownloading = #False
SetGadgetState(#Progress,0)
If CurrentSize < FileSize
DeleteFile(Filename.s)
EndIf
Else
MessageRequester("Warning!","Download failed!",#MB_ICONWARNING)
EndIf
InternetCloseHandle_(hURL)
InternetCloseHandle_(hInetCon)
InternetCloseHandle_(hInet)
DisableToolBarButton(#ToolBar,#Cancel,#True)
StatusBarText(#StatusBar,0,"")
CompilerElse
; ***************************
; Other OS code
; ***************************
CompilerEndIf
EndProcedure
Procedure.s GetDownloadURL()
; Extract the HTML code from the WebGadget
Protected Source.s
If (FindString(Source,"iframe",1))
Source.s=GetGadgetItemText(#Web,#PB_Web_SelectedText)
Else
Source.s=GetGadgetItemText(#Web,#PB_Web_HtmlCode)
EndIf
; Extract the VideoURL from HTML code
Protected i,j
Protected Result.s
i=FindString(Source,UrlBegin,1)+Len(UrlBegin)
j=FindString(Source,UrlEnd,i)
Result = UrlInit+Mid(Source,i,j-i)
; Decode the VideoURL if necessary
Select LCase(UrlDecodeMode)
Case "url"
Result = DecodeURL(Result)
Default
EndSelect
ProcedureReturn Result
EndProcedure
Procedure.s GetVideoTitle()
; Extract the HTML code from the WebGadget
Protected Source.s=GetGadgetItemText(#Web,#PB_Web_HtmlCode)
; Extract the VideoName from HTML code (if not use default name)
Protected i,j
Protected Result.s ="default_video_"+SourceName+"_"+FormatDate("%yyyy%mm%dd_%hh%ii%ss",Date())
i=FindString(Source,"<title>",1)
j=FindString(Source,"</title>",i)
If (i And j)
i+Len("<title>")
Source = Mid(Source,i,j-i)
i=FindString(Source,TitleBegin,1)
j=FindString(Source,TitleEnd,i)
If i=0 : i=1 : EndIf
If j=0 : j=Len(Source)+1 : EndIf
Result = Mid(Source,i,j-i)
EndIf
ProcedureReturn Result
EndProcedure
Procedure.s GetVideoId()
; Extract the HTML code from the WebGadget
Protected Source.s=GetGadgetItemText(#Web,#PB_Web_HtmlCode)
; Extract the VideoName from HTML code
Protected i,j
Protected Result.s =""
If FindString(Source,"<body",1)
i=FindString(Source,IdBegin,1)
If (i)
i+Len(IdBegin)
j=FindString(Source,IdEnd,i)
If (j)
Result = Mid(Source,i,j-i)
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure.s GetVideoFilename(File.s) ; Get normalized filename
Protected n
Protected c.s, Out.s
For n=1 To Len(File)
c.s=Mid(File,n,1)
If FindString(c,"\",1)
Out.s+" "
ElseIf FindString(c,"/",1)
Out.s+" "
ElseIf FindString(c,":",1)
Out.s+" "
ElseIf FindString(c,"?",1)
Out.s+" "
ElseIf FindString(c,"*",1)
Out.s+" "
ElseIf FindString(c,"<",1)
Out.s+" "
ElseIf FindString(c,">",1)
Out.s+" "
ElseIf FindString(c,"|",1)
Out.s+" "
ElseIf FindString(c,Chr(34),1)
Out.s+" "
Else
Out.s+c
EndIf
Next
ProcedureReturn Out
EndProcedure
;}
;{ Load Preferences
CompilerIf #PB_Compiler_Debugger
Ini.s="D:\.............\PureTube.ini" ; for code debugging
Xml.s="D:\.............\PureTube.xml" ; for code debugging
CompilerElse
Ini.s=GetPathPart(ProgramFilename())+StringField(GetFilePart(ProgramFilename()),1,".")+".ini"
Xml.s=GetPathPart(ProgramFilename())+StringField(GetFilePart(ProgramFilename()),1,".")+".xml"
CompilerEndIf
OpenPreferences(Ini)
Path.s=ReadPreferenceString("Path","c:\")
LastUrl.s=ReadPreferenceString("LastUrl","http://www.youtube.com")
IsMaximized.b=ReadPreferenceLong("IsMaximized",0)
SourceName.s =ReadPreferenceString("LastSource","YouTube")
InitSourceList(Xml)
InitSourceParser(Xml)
;}
;{ Visual Design
OpenWindow(0,0,0,1024,768,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget)
SetWindowTitle(0,#Title+SourceName+#TitleNext+Path)
CreateGadgetList(WindowID(0))
WebGadget(#Web,10,30,1024-20,768-60,LastUrl)
CreateToolBar(#ToolBar,WindowID(0))
ToolBarImageButtonEx(#ToolBar,#Home,ImageID(CatchImage(#PB_Any,?Home)),RemoveString(SourceURL,"http://"))
ToolBarImageButtonEx(#ToolBar,#Back,ImageID(CatchImage(#PB_Any,?Back)),"Back")
ToolBarImageButtonEx(#ToolBar,#Forward,ImageID(CatchImage(#PB_Any,?Forward)),"Forward")
ToolBarSeparator()
ToolBarImageButtonEx(#ToolBar,#Folder,ImageID(CatchImage(#PB_Any,?Chemin)),"Download Folder")
ToolBarImageButtonEx(#ToolBar,#Sources,ImageID(CatchImage(#PB_Any,?Options)),"Select Video Source")
ToolBarSeparator()
ToolBarImageButtonEx(#ToolBar,#Download,ImageID(CatchImage(#PB_Any,?Save)),"Download")
ToolBarImageButtonEx(#ToolBar,#Cancel,ImageID(CatchImage(#PB_Any,?Stop)),"Cancel Download")
CreateStatusBar(#StatusBar,WindowID(0))
AddStatusBarField(150)
AddStatusBarField(3000)
ProgressBarGadget(#Progress,170,5,1024-181,20,0,100, #PB_ProgressBar_Smooth)
DisableToolBarButton(#ToolBar,#Cancel,#True)
DisableToolBarButton(#ToolBar,#Download,#True)
If IsMaximized : SetWindowState(0,#PB_Window_Maximize) : EndIf
CreatePopupMenu(#FolderMenu)
MenuItem(#FolderOpen,"Explore Download Folder...")
MenuBar()
MenuItem(#FolderSetup,"Select Folder...")
Procedure WebNavigation(Gadget, url.s)
ProcedureReturn #True
EndProcedure
SetGadgetAttribute(#Web,#PB_Web_NavigationCallback,@WebNavigation())
;}
;{ Event Management
Repeat
evt=WaitWindowEvent()
If IsThread(Tid)=0 And Len(VideoId)>0 ; If not Downloading and Video exists
DisableToolBarButton(#ToolBar,#Download,#False) ; Enable Download
Else
DisableToolBarButton(#ToolBar,#Download,#True) ; Disable Download
EndIf
Select evt
Case #PB_Event_SizeWindow
ResizeGadget(#Web,10,30,WindowWidth(0)-20,WindowHeight(0)-60)
ResizeGadget(#Progress,170+20,5,WindowWidth(0)-181-20,20)
Case #PB_Event_Gadget
Select EventGadget()
Case #Web
Select EventType()
Case #PB_EventType_TitleChange
VideoId = ""
StatusBarText(#StatusBar,1," "+GetGadgetText(#Web)) ; Show PageURL
Default
VideoId = GetVideoId()
If IsThread(Tid)=0
StatusBarText(#StatusBar,0," "+VideoId) ; Show VideoId
EndIf
EndSelect
EndSelect
Case #PB_Event_Menu
Select EventMenu()
Case #Home
SetGadgetText(#Web,SourceURL)
Case #Back
SetGadgetState(#Web,#PB_Web_Back)
Case #Forward
SetGadgetState(#Web,#PB_Web_Forward)
Case #Download
If Not IsDownloading And Len(VideoId)>0
VideoTitle = GetVideoTitle()
DownloadFilename = Path+GetVideoFilename(VideoTitle)+".flv"
DownloadURL = GetDownloadURL()
Tid = CreateThread(@SaveVideoFile(),VideoId)
EndIf
Case #Cancel
StopDownload = #True
IsDownloading = #False
SetGadgetState(#Progress,0)
DisableToolBarButton(#ToolBar,#Cancel,#True)
Case #Folder
DisplayPopupMenu(#FolderMenu,WindowID(0),WindowX(0)+82,WindowY(0)+54) ; show folder menu
Case #FolderOpen
SetGadgetText(#Web,Path)
Case #FolderSetup
temp.s=PathRequester("Backup Video Path",Path)
If temp<>""
Path=temp
SetWindowTitle(0,#Title+SourceName+#TitleNext+Path)
EndIf
Case #Sources
DisplayPopupMenu(#SourceMenu,WindowID(0),WindowX(0)+106,WindowY(0)+54) ; show source menu
Default
SourceName = GetMenuItemText(#SourceMenu, EventMenu()) ; new source name
InitSourceParser(Xml) ; new source parser
ToolBarToolTip(#ToolBar,#Home,RemoveString(SourceURL,"http://")) ; refresh toolbar
SetGadgetText(#Web,SourceURL) ; refresh web content
EndSelect
EndSelect
Until evt=#PB_Event_CloseWindow
;}
;{ Save Preferences
WritePreferenceString("Path",Path)
WritePreferenceString("LastUrl",GetGadgetText(#Web))
WritePreferenceString("LastSource",SourceName)
WritePreferenceLong("IsMaximized", (#True And GetWindowState(0) = #PB_Window_Maximize))
;}
; jaPBe Version=3.7.7.653
; FoldLines=002E006400300000005F0000006600AC0067000000AE0170013C000001510000
; FoldLines=0172018201A601F101F301F8
; Build=48
; Language=0x0000 Language Neutral
; FirstLine=51
; CursorPosition=370
; EnableThread
; EnableXP
; UseIcon=PureTube.ico
; ExecutableFormat=Windows
; Executable=
; DontSaveDeclare
; EOF
XML examples
Code: Select all
<?xml version="1.0" encoding="iso-8859-1"?>
<sources>
<source id="YouTube">
<homepage url="http://www.youtube.com" />
<vid begin="video_id=" end="& #38;" />
<title begin="YouTube - " end="" />
<download
url="http://cache.googlevideo.com/get_video?video_id="
begin="video_id="
end="& #38;"
decode="" />
</source>
<source id="DailyMotion">
<homepage url="http://www.dailymotion.com" />
<vid begin="key%3D" end="& #34;);" />
<title begin="Video " end=" - " />
<download
url="http://www.dailymotion.com/get/"
begin="http%3A%2F%2Fwww.dailymotion.com%2Fget%2F"
end="& #34;);"
decode="url" />
</source>
<source id="GoogleVideo">
<homepage url="video.google.com" />
<vid begin="/videoplay?docid\u003d" end="& #34;" />
<title begin="" end=" - " />
<download
url="http://vp.video.google.com"
begin="http%3A%2F%2Fvp.video.google.com"
end="& #38;messagesUrl"
decode="url" />
</source>
</sources>