Python has nice libraries urllib and urllib2 we can use for our purpose. urllib2 provides nice feature of request header modification. Here's my recipe python version.
import urllib2
from threading import Thread
class Downloader:
def __init__(self):
pass
def downloadFile(self, url, num_streams, dest_fname):
file_size = self.getContentLength(url)
if not self.supportsPartialContent(url):
print "The server doesn't support partial content!! Resuming with Single Stream"
self.downloadStream(url, dest_fname, "bytes=0-"+`file_size`)
return
initial = 0
block = int(file_size / num_streams)
final = block
files = []
threads = []
for i in xrange(num_streams):
drange = "bytes=" + `initial` + "-" + `final`
print drange
files.append("fileparts" + `i`)
t = Thread(target=self.downloadStream, args=(url, files[i], drange))
threads.append(t)
initial = final
final = (final + block) if (i < num_streams-2) else file_size
[t.start() for t in threads]
[t.join() for t in threads]
self.concatFiles(files, dest_fname);
def concatFiles(self, original, dest):
final_file = open(dest, 'wb')
for f in original:
fopener = open(f, 'rb')
final_file.write(fopener.read())
fopener.close()
final_file.close()
return
def supportsPartialContent(self, url):
request = urllib2.Request(url)
request.add_header("Range", "bytes=0-10")
opener = urllib2.urlopen(request)
print opener.getcode()
return True if opener.getcode() == 206 else False
def downloadStream(self, url, file_name, range):
request = urllib2.Request(url)
request.add_header("Range", range)
opener = urllib2.urlopen(request)
f = open(file_name, "wb")
f.write(opener.read())
f.close()
def getContentLength(self, url):
content = urllib2.urlopen(url)
meta = content.info()
file_size = int(meta.getheaders("Content-Length")[0])
return file_size
url = "http://shresthasushil.com.np/img/velocious.jpg"
num_streams = 5
dest_fname = "testfile"
dman = Downloader()
dman.downloadFile(url, num_streams, dest_fname)
I suggest you take only the concept and try make your own recipe. Happy coding guys.
This comment has been removed by the author.
ReplyDelete