Python‎ > ‎

Librerie

partialget.py

Questa libreria nasce dalla necessità di potere scaricare file di grosse dimensioni riprendendo da dove si era rimasti nel caso di disconnessione o altri problemi di rete.
Uso questa libreria con successo nel programma VCAST all'interno di thread per il download di file anche di 2 GigaByte.
Nella variabile temp_file_pattern c'è il formato con cui il file viene memorizzto su disco prima di essere completo: questo file sarà poi rinominato una volta completato.
La funzione get ha i parametri di chiamate simili alla urlretreive della urllib. Si occupa del controllo del file completo e di verificare a che punto del download si è arrivati.
__pget invece fà il lavoro vero e proprio; da dire che era stato previsto sia il download conm protocollo http che ftp, ma l'ftp non è mai stato implementato.
import httplib
import socket
import os

temp_file_pattern = ".%s.~pg"

def get(url, filename = None, reporthook = None):
if filename == None:
filename = url[url.rfind('/')+1:]
if os.path.exists(temp_file_pattern % filename):
sz = os.path.getsize(temp_file_pattern % filename)
f = temp_file_pattern % filename
elif os.path.exists(filename):
sz = os.path.getsize(filename)
f = filename
else:
sz = 0
f = temp_file_pattern % filename
d,h = __pget(url, f, sz, reporthook)
#rename del file se completato
tmp = '0'
for x,y in h:
if x.lower() == 'Content-Range'.lower():
tmp = y
flen = int(tmp[tmp.rfind('/')+1:])
if os.path.exists(f):
if flen == os.path.getsize(f):
os.rename(f,filename)
return d,h

def __pget(url, filename, segmento=0, reporthook = None):
socket.timeout = 60
lista = url.strip('/').split('/')
host = lista[1]
if host=='':
host = lista[2]
pt = url[url.find(host)+len(host):]

if lista[0]=='http:':
h = httplib.HTTPConnection(host)
h.request("GET", pt, headers = {"Range":"bytes=%i-\n" % segmento})

r = h.getresponse()
bytes = int(r.getheader('Content-Length',0))
if r.status==301: #Moved Permanently
html = r.read()
href = html.find('href="')+len('href="')
fine = html.find('"', href)
return __pget(html[href:fine],filename,segmento,reporthook = reporthook)

fout = open(filename,'ab')
data = 0
rs = " "
while data < bytes and len(rs):
if reporthook:
reporthook(data,1,bytes)
rs = r.read(1024)
data += len(rs)
fout.write(rs)
if reporthook:
reporthook(data,1,bytes)

return data, r.getheaders( )

if __name__ == "__main__":
#test
d, h = get ("http://www.gbinside.com/150.bin")
print d, h
raw_input('Press Enter...')
Comments