#!/usr/bin/python

# this code demonstrates how slow Jython is to download from a URL (I tried FTP and HTTP)
# compared to Python.  Jython seems to be 600 times slower.  Go ahead, try it with both
# interpreters.  It's crazy slow in Jython.

from urllib2 import Request, urlopen, URLError, HTTPError
import urllib
import time
import os.path

# download speed test using different download methods

class DownloadTest(object):

    def download(self, url, localPath):
        """
        Download a file from a url to a local path.  Returns downloaded file
        path on success, None otherwise.
        """

        if os.path.isdir(localPath):
            url_components = url.rsplit('/', 1)
            url_basename = url_components[-1]
            localPath = os.path.join(localPath, url_basename)
        try:
            #file_location,info = urllib.urlretrieve(url, localPath, simpleReportHook)
            file_location,info = urllib.urlretrieve(url, localPath)
        except Exception, e:
            print "Got exception when trying to download '" + url + "' to " + localPath + ":"
            print e
        else:
            # everything is fine
            return file_location
        return None

    def downloadFaster(self, url, localPath):
        """
        My previous attempt at writing a download function (using urllib.urlretrieve)
        was agonizingly slow.  I suspect it had something to do with urlretrieve's
        choice of block sizes.  Let's try using urllib2.

        Download a file from a url to a local path.  Returns downloaded file
        path on success, None otherwise.
        """

        success = False
        req = Request(url)
        try:
            response = urlopen(req)
        except HTTPError, e:
            print 'The server couldn\'t fulfill the request.'
            print 'Error code: ', e.code
        except URLError, e:
            print 'We failed to reach a server.'
            print 'Reason: ', e.reason
        else:
            success = True

        if not success:
            return
        
        blockSize = 32*1024

        if os.path.isdir(localPath):
            url_components = url.rsplit('/', 1)
            url_basename = url_components[-1]
            localPath = os.path.join(localPath, url_basename)

        print "Downloading '%s' to '%s'" % (url, localPath)

        try:
            output_file = open(localPath, 'w+b', 0)
            # TODO: dynamically adjust block size based on performance?

            while True:
                buffer = response.read(blockSize)
                if buffer:
                    output_file.write(buffer)
                else:
                    break
            output_file.close()
        except Exception, e:
            print "Exception occurred downloading '%s' to '%s': %s" % (url, localPath, e)
            return

        # everything is fine
        return localPath


if __name__ == "__main__":
    dt = DownloadTest()
    #url = "http://neo.pgp.com/packages/ovidserver/English/2.10.0.ver/Linux/505.bld/ovidserver-docs-2.10.0.505-1.i386.rpm"
    url = "http://python.org/ftp/python/2.6.1/Python-2.6.1.tgz"
    t1 = time.time()
    downloaded_file_path = dt.download(url, "/tmp")
    t2 = time.time()
    print "time elapsed for urllib.urlretrieve(): %s" % str(int(t2 - t1))
    t1 = time.time()
    downloaded_file_path = dt.downloadFaster(url, "/tmp")
    t2 = time.time()
    print "time elapsed for urllib2.urlopen(): %s" % str(int(t2 - t1))

    print url
    print downloaded_file_path
