Télécharger un fichier ?

Programmation d'applications complexes
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Télécharger un fichier ?

Message par Crystal Noir »

Salut tous :)

Je cherche un moyen de télécharger des fichiers sans utiliser l'api windows, car je voudrais que ce soit multiplateforme. En clair j'veux pouvoir faire ceci sous linux.

Mais j'ai beau cherché, je ne trouve que des trucs urldownloadfile_ donc pour windows, quelqu'un a une idée ?

merci d'avance :)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Télécharger un fichier ?

Message par Backup »

Crystal Noir a écrit :Salut tous :)

Je cherche un moyen de télécharger des fichiers sans utiliser l'api windows, car je voudrais que ce soit multiplateforme. En clair j'veux pouvoir faire ceci sous linux.

Mais j'ai beau cherché, je ne trouve que des trucs urldownloadfile_ donc pour windows, quelqu'un a une idée ?

merci d'avance :)
l'utilisation du protocole FTP via un Telnet (runprograme)...
et a toi les "PUT","Get" :)
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

non ca me va pas bien comme système...

Par contre j'ai trouvé ceci :

Code : Tout sélectionner

InitNetwork()

#TIMEOUT = 1500

Procedure.s ReceiveLine(ConnectionID)
  Text.s = ""
  While char.b <> #LF
    char = 0
    ReceiveNetworkData(ConnectionID, @char, 1)
    If char <> 0
      Text.s + Chr(char)
    EndIf
  Wend
 
  ProcedureReturn RemoveString(RemoveString(Text, #CR$), #LF$)
EndProcedure

Procedure HTTPRequest(URL.s, *EndSize.LONG, PacketSize, *Callback)
  Protected Size.l, Data_.s, s.l, Method.s, File.s, Content.s, Text.s, Length.l, Line.s
  Protected CurSize.l, oSize.l, t.l, ConnectionID.l
 
  If Left(URL, 7) = "http://" : URL = Right(URL, Len(URL)-7) : EndIf
  s = FindString(URL, "/", 1)
  Host.s = "" : File.s = ""
  If s <> 0 : Host.s = Left(URL, s-1) : File.s = Right(URL, Len(URL)-s) : Else : Host = URL : EndIf
 
  s = FindString(File, "?", 1)
  If s <> 0
    Method.s = "POST"
    File = Left(File, s)
    Content.s = Right(File, Len(File)-(s+1))
  Else
    Method.s = "GET"
    Content.s = ""
  EndIf
 
 
  ConnectionID = OpenNetworkConnection(Host, 80)
  If ConnectionID
    Data_.s = Method+" /"+File+" HTTP/1.0"+#CRLF$
    Data_.s + "Host: "+Host+#CRLF$
    Data_.s + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7"+#CRLF$
    If Content <> ""
      Data_.s + "Connection: close"+#CRLF$
      Data_.s + "Content-Type: text/html"+#CRLF$
      Data_.s + "Content: "+Content.s+#CRLF$+#CRLF$
    Else
      Data_.s + "Connection: close"+#CRLF$+#CRLF$
    EndIf
   
    SendNetworkString(ConnectionID, Data_)
    While NetworkClientEvent(ConnectionID) <> 2 : Delay(10) : Wend
   
    Length = 0
    Line.s = ""
    Repeat
      Line = ReceiveLine(ConnectionID)
      Select LCase(StringField(Line, 1, ":"))
        Case "content-length"
         
          Length = Val(Trim(StringField(Line, 2, ":")))
      EndSelect
    Until Len(Trim(Line)) <= 4
   
    Size = 0
    If Length <> 0
     
      *Result = AllocateMemory(Length)
     
      While Size < Length
        If CurSize > 0
          Size + CurSize
          If *Callback
            CallFunctionFast(*Callback, Size, Length)
          EndIf
        EndIf
        If Size > (Length-PacketSize)
          PacketSize = Length-Size
        EndIf
        If PacketSize > 0
        CurSize = ReceiveNetworkData(ConnectionID, *Result+Size, PacketSize)
        EndIf
      Wend
     
    Else
     
      *Buffer = AllocateMemory(PacketSize)
      *Result = AllocateMemory(1)
      t = ElapsedMilliseconds()
      While ElapsedMilliseconds()-t <= #TIMEOUT
        If NetworkClientEvent(ConnectionID) = 2
          CurSize = ReceiveNetworkData(ConnectionID, *Buffer, PacketSize)
          If CurSize > 0
            oSize = Size
            Size + CurSize
            *Result = ReAllocateMemory(*Result, Size)
            CopyMemory(*Buffer, *Result+oSize, CurSize)
            If *Callback
              CallFunctionFast(*Callback, Size, 0)
            EndIf
          EndIf
          t = ElapsedMilliseconds()
        EndIf
      Wend
      Length = Size
     
    EndIf
   
    *EndSize\l = Length
    If *Callback
      CallFunctionFast(*Callback, Size, Length)
    EndIf
   
    CloseNetworkConnection(ConnectionID)
   
    ProcedureReturn *Result
  EndIf
EndProcedure

Procedure HTTPRequest_Password(URL.s, *EndSize.LONG, PacketSize, Username.s, Password.s, *Callback)
  Protected Size.l, Data_.s, s.l, Method.s, File.s, Content.s, Text.s, Length.l, Line.s
  Protected CurSize.l, oSize.l, t.l, ConnectionID.l
 
  If Left(URL, 7) = "http://" : URL = Right(URL, Len(URL)-7) : EndIf
  s = FindString(URL, "/", 1)
  Host.s = "" : File.s = ""
  If s <> 0 : Host.s = Left(URL, s-1) : File.s = Right(URL, Len(URL)-s) : Else : Host = URL : EndIf
 
  s = FindString(File, "?", 1)
  If s <> 0
    Method.s = "POST"
    File = Left(File, s)
    Content.s = Right(File, Len(File)-(s+1))
  Else
    Method.s = "GET"
    Content.s = ""
  EndIf
 
  InputBuffer.s = Username+":"+Password
  OutputBuffer.s = Space(256)
  Base64Encoder(@InputBuffer, Len(InputBuffer), @OutputBuffer, 255)
 
  ConnectionID = OpenNetworkConnection(Host, 80)
  If ConnectionID
    Data_.s = Method+" /"+File+" HTTP/1.0" + #CRLF$
    Data_.s + "Host: "+Host + #CRLF$
    Data_.s + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7" + #CRLF$
    Data_.s + "Authorization: Basic "+ OutputBuffer + #CRLF$
    If Content <> ""
      Data_.s + "Connection: close" + #CRLF$
      Data_.s + "Content-Type: text/html" + #CRLF$
      Data_.s + "Content: "+Content.s +#CRLF$ + #CRLF$
    Else
      Data_.s + "Connection: close" + #CRLF$ + #CRLF$
    EndIf
   
    SendNetworkString(ConnectionID, Data_)
    While NetworkClientEvent(ConnectionID) <> 2 : Delay(10) : Wend
   
    Length = 0
    Line.s = ""
    Repeat
      Line = ReceiveLine(ConnectionID)
      Select LCase(StringField(Line, 1, ":"))
        Case "content-length"
         
          Length = Val(Trim(StringField(Line, 2, ":")))
      EndSelect
    Until Len(Trim(Line)) <= 4
   
    Size = 0
    If Length <> 0
     
      *Result = AllocateMemory(Length)
     
      While Size < Length
        If CurSize > 0
          Size + CurSize
          If *Callback
            CallFunctionFast(*Callback, Size, Length)
          EndIf
        EndIf
        If Size > (Length-PacketSize)
          PacketSize = Length-Size
        EndIf
        If PacketSize > 0
        CurSize = ReceiveNetworkData(ConnectionID, *Result+Size, PacketSize)
        EndIf
      Wend
     
    Else
     
      *Buffer = AllocateMemory(PacketSize)
      *Result = AllocateMemory(1)
      t = ElapsedMilliseconds()
      While ElapsedMilliseconds()-t <= #TIMEOUT
        If NetworkClientEvent(ConnectionID) = 2
          CurSize = ReceiveNetworkData(ConnectionID, *Buffer, PacketSize)
          If CurSize > 0
            oSize = Size
            Size + CurSize
            *Result = ReAllocateMemory(*Result, Size)
            CopyMemory(*Buffer, *Result+oSize, CurSize)
            If *Callback
              CallFunctionFast(*Callback, Size, 0)
            EndIf
          EndIf
          t = ElapsedMilliseconds()
        EndIf
      Wend
      Length = Size
     
    EndIf
   
    *EndSize\l = Length
    If *Callback
      CallFunctionFast(*Callback, Size, Length)
    EndIf
   
    CloseNetworkConnection(ConnectionID)
   
    ProcedureReturn *Result
  EndIf
EndProcedure

*Buffer = HTTPRequest("http://www.bradan.net/", @Size, 16, 0)
Debug Size
Debug PeekS(*Buffer, Size)
FreeMemory(*Buffer)
alors c'est chouette ca marche si vous mettez une adresse correcte.

Mais le fichier est en mémoire, moi j'le veux sur le disque lol

une idée ?
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

si j'ai bien compris il commence a
"*Buffer" et sa longueur est de "Length" ou "Size"

et ben quelques petit Peek du depart "*Buffer" dans une boucle qui dure "Length"

tu recupere tes octets , dans une variable tableau , puis ecriture dans fichier non ? 8O (ou ecriture direct de l'octet recuperé)

en utilisant des long ça irai meme plus vite :D
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

Justement j'aimerais pouvoir downloader assez rapidement car si c pour faire du bit à bit et qu'il mette trois plombes à dl un fichier de 1 mo ca va pas le faire :(

j'vois pas trop comment faire, sous windows facile avec urldownloadfile mais sous nunux...
meganet
Messages : 317
Inscription : jeu. 20/janv./2005 22:00

Ma procedure pour télécharger un fichier

Message par meganet »

Salut, j'ai fait une procedure pour télécharger un fichier, (je ne les pas encore fini mais si ça peu t'aider).

Code : Tout sélectionner

Procedure URLDownloadToFile(URL$,FilePath$)
EOL$ = Chr(13)+Chr(10)
Position = FindString(URL$, "http://", 1)
If Position=1
Position=FindString(URL$,"/",8)
Position=FindString(URL$,"/",8)
URLL$=Right(URL$,Len(URL$)-7)
HOST$=Left(URLL$,Position-8)
PosiPort=FindString(HOST$,":",1)
If PosiPort = 0
PORT=80
Else
LNGPort=Len(HOST$)-PosiPort
Port$=Right(HOST$,LNGPort)
PORT=Val(Port$)
HOST$=Left(HOST$,Len(HOST$)-LNGPort-1)
EndIf
GET$=Right(URLL$,Len(URLL$)-Position+8)
Else
EndIf

ClientID=OpenNetworkConnection(HOST$,PORT)

If ClientID
SendNetworkString(ClientID,"GET "+GET$+" HTTP/1.1"+EOL$)
SendNetworkString(ClientID,"HOST: "+HOST$+EOL$)
SendNetworkString(ClientID,EOL$)
Buffer = AllocateMemory(32000)
ReceiveNetworkData(ClientID,Buffer,32000)
CloseNetworkConnection(ClientID)
If CreateFile(0,FilePath$)
Text$=PeekS(buffer,32000)
Text$=RTrim(Text$)
WriteString(0,Text$)
CloseFile(0)
OK=1
Else
OK=0
EndIf
FreeMemory(buffer)
ProcedureReturn OK
Else
ProcedureReturn 0
EndIf
EndProcedure
Voilà si tu ne comprend pas tout n'ésite pas.
Et je le répête, je ne les pas fini.[/code]
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

lmerci je vais y jetter un oeil
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

En même temps que je jette un oeil à ce code, juste une question : existe t'il sous linux en purebasic la correspondance de UrldownloadFile ?
meganet
Messages : 317
Inscription : jeu. 20/janv./2005 22:00

Le code avance.

Message par meganet »

Je suis entrain de bosser sur se code, mais il y à quelque dificulté qui son dure à résoudre.
Ca dépend du type de fichier que tu veu télécharger, et où.
Si tu me donne ça, jpeu finir la procedure vite.
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

J'ai regardé le code mais à priori cela ne fonctionne pas avec des fichiers qui ne sont pas du texte. il ajoute également l'entête ce qui est genant....

pour ce linux chuis désespéré.

EDIT : ca peut être n'importe quel type de fichier dont des exécutables.

Je trouve absolument rien qui marche même sur le forum anglais. En plus j'utilise la version 3.94 sous linux, j'évite toujours les bêta. cela dit tout ce que j'ai trouvé ya toujours une erreur dans le code je pige rien.

J'vais finir par changer mes plans lol avec un bmax j'y arrive sur les deux os.

C'est agaçant de pas trouver de solution :(
meganet
Messages : 317
Inscription : jeu. 20/janv./2005 22:00

Voilà la solution!

Message par meganet »

Salut, oui je sais qu'ont pouvaient juste télécharger du texte avec et qu'il rajoutait l'en-tête, c'est pour ça que j'ai corigé la procedure, mintenant tu peu télécharger du texte, des application etc... et l'en-tête vir.
Voilà le code qui contien la procedure, et un example de comment l'utiliser.

Code : Tout sélectionner

Procedure URLDownloadToFile(URL$,FilePath$)
If InitNetwork() = 0
MessageRequester("Impossible d'innitialiser le réseau", "Il est impossible d'innitialiser le réseau.", 0)
ProcedureReturn 0
EndIf
EOL$ = Chr(13)+Chr(10)
Position = FindString(URL$, "http://", 1)
If Position=1
Position=FindString(URL$,"/",8)
URLL$=Right(URL$,Len(URL$)-7)
HOST$=Left(URLL$,Position-8)
PosiPort=FindString(HOST$,":",1)
If PosiPort = 0
PORT=80
Else
LNGPort=Len(HOST$)-PosiPort
Port$=Right(HOST$,LNGPort)
PORT=Val(Port$)
HOST$=Left(HOST$,Len(HOST$)-LNGPort-1)
EndIf
GET$=Right(URLL$,Len(URLL$)-Position+8)
GET$ = ReplaceString(GET$, " ", "%20")
s = FindString(GET$, "?", 1)
If s <> 0
Method$ = "POST"
GET$ = Left(GET$, s)
Param$ = Right(GET$, Len(GET$)-(s+1))
Else
Method$ = "GET"
Param$ = ""
EndIf
Else
MessageRequester("URL format incorrect", "L'URL doit-être du type http://HOST/Fichier", 0)
ProcedureReturn 0
EndIf

ClientID=OpenNetworkConnection(HOST$,PORT)

If ClientID
SendNetworkString(ClientID, Method$+" "+GET$+" HTTP/1.1"+EOL$)
SendNetworkString(ClientID,"HOST: "+HOST$+EOL$)
SendNetworkString(ClientID,"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7"+EOL$)
If Param$ <> ""
SendNetworkString(ClientID,"Connection: close"+EOL$)
SendNetworkString(ClientID,"Content-Type: text/html"+EOL$)
SendNetworkString(ClientID,"Content: "+Param$+EOL$+EOL$)
Else
SendNetworkString(ClientID,"Connection: close"+EOL$+EOL$)
    EndIf
While NetworkClientEvent(ClientID) <> 2
Delay(10)
Wend

Taille = 32000
*Buffer = AllocateMemory(Taille)
Restant = ReceiveNetworkData(ClientID,*Buffer,Taille)

Text$ = PeekS(*Buffer, Restant)
Entete$ = Left(Text$, FindString(Text$, EOL$+EOL$, 1))
Count = CountString(Entete$, "HTTP/1.1 200 OK")
If Count = 0
MessageRequester("Fichier introuvable sur le serveur.", "Le fichier "+GET$+" est introuvable sur "+HOST$+".", 0)
FreeMemory(*Buffer)
ProcedureReturn 0
ElseIf Count = 1

If CreateFile(0,FilePath$)

Structure Corespondance
AdresseMemoire.l
Taille.l
EndStructure

NewList Memoire.Corespondance()

AddElement(Memoire())

Memoire()\AdresseMemoire = *Buffer+Len(Entete$)+3
Memoire()\Taille = Restant-Len(Entete$)-3

;Delay(1500)

Repeat
If restant <= 0
ElseIf Restant > 0
 *Buffer = AllocateMemory(Taille)
Restant = ReceiveNetworkData(ClientID,*Buffer,Taille)
AddElement(Memoire())
Memoire()\AdresseMemoire = *Buffer
Memoire()\Taille = Restant
;Delay(1500)
EndIf

Until Restant = 0

ResetList(Memoire())
NextElement(Memoire())

Repeat
WriteData(0, Memoire()\AdresseMemoire, Memoire()\Taille)
;Delay(10)
FreeMemory(Memoire()\AdresseMemoire)
Until NextElement(Memoire()) = 0

ClearList(Memoire())
CloseNetworkConnection(ClientID)
CloseFile(0)

ProcedureReturn 1
Else
MessageRequester("Impossible de créer le fichier", "Il est impossible de créer le fichier "+FilePath$+".", 0)
FreeMemory(*Buffer)
ProcedureReturn 0
EndIf
Else
MessageRequester("Vous n'êtes pas connecté à un serveur http.", "Vous n'êtes pas connecté sur un serveur http.", 0)
FreeMemory(*Buffer)
ProcedureReturn 0
EndIf
Else
MessageRequester("Impossible de ce connecter", "Il est impossible de ce connecter à l'adresse: "+HOST$+".", 0)
ProcedureReturn 0
EndIf
EndProcedure

URL$=InputRequester("Veuillez entrer l'URL du fichier que vous voulez télécharger.", "URL:", "http://")
FileName$ = GetFilePart(URL$)
FileExtension$ = GetExtensionPart(URL$)
If FileExtension$ = ""
Extension$ = "*"
Else
Extension$ = FileExtension$
EndIf
If FileName$ = ""
DefaultFileName$ = "Default"
Else
DefaultFileName$ = Left(FileName$, Len(FileName$)-Len(Extension$)-1)
EndIf
If Extension$ <> "*"
File$=SaveFileRequester("Où voulez-vous enregistrer le fichier téléchargé?", GetCurrentDirectory()+DefaultFileName$, "*."+Extension$+"|*."+Extension$+"|*.*|*.*", 0)
ElseIf Extension$ = "*"
File$=SaveFileRequester("Où voulez-vous enregistrer le fichier téléchargé?", GetCurrentDirectory()+DefaultFileName$, "*."+Extension$+"|*."+Extension$, 0)
EndIf

If SelectedFilePattern() = 0
If GetExtensionPart(File$) <> Extension$
If Extension$ = "*"
Else
File$ = File$+"."+Extension$
EndIf
EndIf
EndIf

Resultat = URLDownloadToFile(URL$,File$)

If resultat = 0
End
ElseIf resultat = 1
MessageRequester("Le fichier à bien été téléchargé.", "Le fichier vien d'être téléchargé avec succès. Il a été sauvegardé dans: "+File$+".", 0)
End
EndIf
Voilà.
Et là, toutes les commandes utilisées, sont disponibles autan sur Linux, MacOS et Windows.
Si ça ne télécharge pas bien, décommente les Delay() qui sont commenté.
Pour voir l'example sous Windows et le tester sans avoir besoin de le compiler, http://download.site-meganet.com/Download.exe (les Delay() étaient commenté lors de la compilation de cet example).
Si tu trouve un bug, nésite pas!
@+++.
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

cool j'vais regarder ca, je vais le tester sous windows et ensuite sous linux.

J'espère qu'il machera sous la version 3.94 car sous win chuis en version 4 mais sous linux en version 3.94 car làa 4 n'est encore qu'une bêta.

Un question sur le code que j'ai mis au début plus haut, à priori ce code a été donné pour quelqu'un qui voulait faire des dl sous linux, malheureusement chez moi il me fait des erreurs sur les constantes #RF etc... en disant que ce sont des constantes inconnues, quelqu'un a une idée ?
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

Elle marche niquel sur windows.

Sur linux je testerai à midi ou ce soir.

Par contre petite correction :

Ne mets pas le InitNetwork dans ta procédure car si on l'utilise plusieurs fois pb retourne une erreur ce qui est normal :)

Je teste ca sous linux
meganet
Messages : 317
Inscription : jeu. 20/janv./2005 22:00

Bien vue

Message par meganet »

Salut, bien vue pour le InitNetWork().
Et pour la constante #RF de ton code, elle correspond dans le mien à EOL$.
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

à priori ca marche pas sous linux : invalid memory access

avec FreeMemory(Memoire()\AdresseMemoire)

faudra que je regarde de plus près
Répondre